Plot in Flipped Java Coordinates - spatstat

I would like to plot a ppp object from a particle analysis in ImageJ from a greyscale image with size imageSizeX, imageSizeY of point objects Particles$X, Particles$Y in flipped Java coordinates (y0 = top-left).
I have a kind of working solution (example with customization):
library(spatstat)
X <- ppp(Particles$X, Particles$Y, c(0, imageSizeX), c(0, imageSizeY))
plot(x = 0, y = 0, xlim = c(0, imageSizeX), ylim = c(imageSizeY, 0), type = "n", main = "Density",
asp = 1, axes = F, xlab = "X", ylab = "Y")
plot(density(X), xlim = c(1, imageSizeX), ylim = c(imageSizeY, 0), add = T)
plot(X, axes = TRUE, xlim = c(1, imageSizeX), ylim = c(imageSizeY, 0), add = T)
axis(1)
axis(2, las = 2)
which results in the following plot (which omits the legend):
However I need to create an empty plot command with the flipped coordinates (ylim = c(imageSizeY, 0)) and then have to add the spatstat plots.
If I try to plot:
library(spatstat)
X <- ppp(Particles$X, Particles$Y, c(0, imageSizeX), c(0, imageSizeY))
plot(density(X), xlim = c(1, imageSizeX), ylim = c(imageSizeY, 0))
plot(X, axes = TRUE, xlim = c(1, imageSizeX), ylim = c(imageSizeY, 0), add = T)
axis(1)
axis(2, las = 2)
the coordinates are not plotted flipped (ylim = c(imageSizeY, 0)):
Is there a way to flip the plot coordinates in spatstat without a first defining plot command?

This is a bug in plot.ppp. I have fixed it in the current development version of spatstat, version 1.46-1.010 available from the spatstat repository on GitHub
In the current version of spatstat on CRAN (1.46-1) the plot method for windows, plot.owin, does recognise xlim, ylim as you would like, while plot.ppp does not. So if X is a point pattern, you can do
W <- Window(X)
plot(W, xlim=rev(W$xrange), main="The title")
plot(X, add=TRUE, ...)

Related

How to generate two sets of distinct points on a sphere in julia language?

I need to apply the PCA at different points of a spherical cap, but I don’t know how to build these sets of different points, I need at least 2 sets.
Here is a picture with the idea of what I need.
Spherical Cap
If I correctly understand, here is how I would do in R.
library(uniformly)
library(pracma)
library(rgl)
# sample points on a spherical cap
points_on_cap1 <- runif_on_sphericalCap(300, r = 2, h = 0.5)
# convert to spherical coordinates
sphcoords1 <- cart2sph(points_on_cap1)
# sample points on a spherical cap
points_on_cap2 <- runif_on_sphericalCap(300, r = 2, h = 0.5)
# rotate them, because this is the same spherical cap as before
points_on_cap2 <- rotate3d(points_on_cap2, 3*pi/4, 1, 1, 1)
# convert to spherical coordinates
sphcoords2 <- cart2sph(points_on_cap2)
# 3D plot
spheres3d(0, 0, 0, radius = 2, alpha = 0.5, color = "yellow")
points3d(points_on_cap1, color = "blue")
points3d(points_on_cap2, color = "red")
# 2D plot (of the spherical coordinates)
plot(
sphcoords1[, 1:2], xlim = c(-pi, pi), ylim = c(-pi/2, pi/2),
pch = 19, col = "blue"
)
points(sphcoords2[, 1:2], pch = 19, col = "red")
Do I understand?
Here is the function runif_on_sphericalCap:
function(n, r = 1, h){
stopifnot(h > 0, h < 2*r)
xy <- runif_in_sphere(n, 2L, 1)
k <- h * apply(xy, 1L, crossprod)
s <- sqrt(h * (2*r - k))
cbind(s*xy, r-k)
}
It always samples on a spherical cap with symmetry axis joining the center of the sphere to the North pole. That is why I do a rotation, to get another spherical cap.
Say me if I understand and I'll try to help you to convert the code to Julia.
EDIT: Julia code
using Random, Distributions, LinearAlgebra
function runif_in_sphere(n::I, d::I, r::R) where {I<:Integer, R<:Number}
G = Normal()
sims = rand(G, n, d)
norms = map(norm, eachrow(sims))
u = rand(n) .^ (1/d)
return r .* u .* broadcast(*, 1 ./ norms, sims)
end
function runif_on_sphericalCap(n::I, r::Number, h::Number) where {I<:Integer}
if h <= 0 || h >= 2*r
error("")
end
xy = runif_in_sphere(n, 2, 1.0)
k = h .* map(x -> dot(x,x), eachrow(xy))
s = sqrt.(h .* (2*r .- k))
return hcat(broadcast(*, s, xy), r .- k)
end

R plotly line color by value range

I would like to make this kind of graph (here from Our World In data ) where the line color varies by value range.
edit : adding a screenshot to make it clearer :
With plotly, I found this example but working with type = scatter and mode = markers plot and not with lines:
x <- seq(from = -2,
to = 2,
b = 0.1)
y <- sin(x)
p11 <- plot_ly() %>%
add_trace(type = "scatter",
x = ~x,
y = ~y,
mode = "markers",
marker = list(size = 10,
color = colorRampPalette(brewer.pal(10,"Spectral"))(41))) %>%
layout(title = "Multicolored sine curve",
xaxis = list(title = "x-axis"),
yaxis = list(title = "y-axis"))
p11
is there any ways to use the colorRampPalette or values range but with line (actually it's a time series)
x <- seq(from = -2,
to = 2,
b = 0.1)
y <- sin(x)
p11 <- plot_ly() %>%
add_trace(type = "scatter",
x = ~x,
y = ~y,
mode = "lines",
line = list(width = 1,
color = colorRampPalette(brewer.pal(10,"Spectral"))(41))) %>%
layout(title = "Multicolored sine curve",
xaxis = list(title = "x-axis"),
yaxis = list(title = "y-axis"))
p11
Thank you
You can, but the more points you have the better it will look. Note that I change the .1 in x, to .001.
library(plotly)
library(RColorBrewer)
x <- seq(from = -2,
to = 2,
b = 0.001)
y <- sin(x)
z = cut(x, breaks = 5, include.lowest = T)
p11 <- plot_ly() %>%
add_lines(x = ~x,
y = ~y,
color = ~z,
colors = colorRampPalette(brewer.pal(10,"Spectral"))(length(x))) %>%
layout(title = "Multicolored sine curve",
xaxis = list(title = "x-axis"),
yaxis = list(title = "y-axis"))
p11
If I change that .001 back to .1, it's a bit ugly! You can see the gaps.

Apply filters to Hough Line Detection

In my application, I use Hough Line Detection to detect lines inside an image. What I'm trying to do is to retrieve only the lines that compose the border and the corners of each square of the chessboard. How can I apply filters to obtain a clear view of the lines?
My idea is to apply filters to check the angle between each line(90 degrees) or the distance to get only the lines that count. The final goal will be to obtain the intersection between these lines to get the coordinates of each square.
Code:
chessBoard = cv2.imread('img.png')
gray = cv2.cvtColor(chessBoard,cv2.COLOR_BGR2GRAY)
dst = cv2.Canny(gray, 50, 200)
lines= cv2.HoughLines(dst, 1, math.pi/180.0, 100, np.array([]), 0, 0)
a,b,c = lines.shape
for i in range(a):
rho = lines[i][0][0]
theta = lines[i][0][1]
a = math.cos(theta)
b = math.sin(theta)
x0, y0 = a*rho, b*rho
pt1 = ( int(x0+1000*(-b)), int(y0+1000*(a)) )
pt2 = ( int(x0-1000*(-b)), int(y0-1000*(a)) )
cv2.line(chessBoard, pt1, pt2, (0, 255, 0), 2, cv2.LINE_AA)

Matplotlib - Fill_Between doesn't seem work

I'm new to python and learned a ton over the past 2 weeks. I have just started learning and experimenting with matplotlib.pylot. In my code, I have 3 seperate simple graphs on the same plot, in the third graph there are 2 lines. I am trying to have a green fill_between when y2 > y3, and red fill_between when y3 > y2. I have taken a look at other code, and they look identical to mine, but for some reason it doesn't work.
Any help?
There are a few commented lines, they are just experimentation.
import matplotlib.pyplot as plt
import random
from matplotlib import style
style.use('fivethirtyeight')
def create_points(nPoints):
xs = []
ys = []
for i in range(nPoints):
rand = random.randrange(0,3*nPoints)
xs.append(i)
ys.append(rand)
return xs, ys
x,y = create_points(200)
x1,y1 = create_points(200)
x2, y2 = create_points(200)
x3, y3 = create_points(200)
fig = plt.figure()
ax1 = plt.subplot2grid((6,1), (0,0), rowspan = 1, colspan = 1)
plt.title('Subplot2grid Method')
plt.ylabel('Plot 1')
ax2 = plt.subplot2grid((6,1), (1,0), rowspan = 4, colspan = 1, sharex = ax1)
plt.ylabel('Plot 2')
ax2_xtwin = ax2.twinx()
ax3 = plt.subplot2grid((6,1), (5,0), rowspan = 1, colspan = 1, sharex = ax1)
plt.xlabel('x')
plt.ylabel('Plot 3')
ax2_xtwin.fill_between(x,0,y, facecolor = '#0079a3', alpha = 0.4)
#ax2v.axes.yaxis.set_ticklables([])
ax2_xtwin.grid(False)
ax2_xtwin.set_ylim(0, 1.5*max(y))
ax3.plot(x2, y2, x2, y3, linewidth = 1, label = 'x2y2 plot', color = 'k')
#ax3.plot(x3, y3, linewidth = 1, label = 'x3y3 plot', color = 'firebrick')
ax3.fill_between(x2, y2, y3, where = (y2 >= y3), facecolor = 'darkgreen',
edgecolor = 'g', alpha = 0.5, interpolate = True)
ax3.fill_between(x2, y2, y3, where = (y2 <= y3), facecolor = 'firebrick',
edgecolor = 'r', alpha = 0.5, interpolate = True)
#Print Points
ax1.plot(x, y, linewidth = 1, label = 'xy plot', color = 'gold')
ax2.plot(x1, y1, linewidth = 1, label = 'x1y1 plot', color = 'sandybrown')
#ax3.plot(x2, y2, linewidth = 1, label = 'x2y2 plot', color = 'darkgreen')
#ax3.plot(x3, y3, linewidth = 1, label = 'x3y3 plot', color = 'firebrick')
plt.subplots_adjust(left = 0.15, bottom = 0.1, right = 0.9, top = 0.9,
wspace = 0.2, hspace = 0)
plt.show()
Edit:
Sorry I miss-understood your question.
If you delete color='k' in ax3.plot and mask the y2 after the first fill_between it works fine.
Change to...
ax3.plot(x2, y2, x2, y3, linewidth = 1, label = 'x2y2 plot')
ax3.fill_between(x2, y2, y3, where = (y2 >= y3), color = "g",
edgecolor = 'g', alpha = 0.5, interpolate = True)
y2 = np.ma.masked_greater(y2, y3)
ax3.fill_between(x2, y2, y3, where = (y2 <= y3), color="r",
edgecolor = 'r', alpha = 0.5, interpolate = True)
I'm not sure why but the facecolor didn't work on my side, so I changed to color.
Hope this helps.

How to plot 3D voxels with given coordinates on a sphere using matplotlib

I'm currently trying to make a 3D voxels plot with know coordinates on a sphere. The x, y and z coordinates are lists filtered from a CSV. Additionally I have another list with same length as x, y and z containing the color of the voxel. With these list I want to create a 3D voxel sphere.
This I already accomplished using a 3D scatter plot (matplotlib) but the result is not very clear:
x = []
y = []
z = []
c = []
red = (1, 0, 0, 1)
green = (0, 1, 0, 1)
blue = (0, 0, 1, 1)
black = (0, 0, 0, 1)
for i in range(len(result)):
x.append(20 * math.sin(math.radians(90 - result[i][1])) * math.cos(math.radians(result[i][0])))
y.append(20 * math.sin(math.radians(90 - result[i][1])) * math.sin(math.radians(result[i][0])))
z.append(20 * math.cos(math.radians(90 - result[i][1])))
if result[i][2] == 1000:
c.append(black)
elif result[i][2] > 500:
c.append(red)
elif 200 < result[i][2] <= 500:
c.append(blue)
else:
c.append(green)
fig = pyplot.figure()
ax = Axes3D(fig)
ax.grid(True)
ax.scatter(x, y, z, c=c, s=500)
pyplot.show()
3D-Scatter

Resources