Changing scale of axes in Julia - julia

I am importing some numbers from two CSV files and plotting a heatmap according to the below code
height = readdlm("./height.csv", ';', Float64)
deformation = readdlm("./deformation.csv", ';', Float64)
heatmap(10^9 .* (height - deformation),
aspect_ratio=:equal,
title="Height - Deformation")
The plotting libraries that I have used to do this are GR and Plotly with the Plots meta package. Currently, the x-axis and y-axis of the heatmap consists of 256 units of length. It is possible to change the scale of the x-axis and y-axis. For instance, could I make each tick on the x-axis have length 256/900 of the current unit length?

You can use heatmap(x, y, z) for this.
I suppose you have 256 entries in each dimension and a total of 65536 entries.
x = 1/256:1/256:1 # an iterable with length 256
y = 1/256:1/256:1 # an iterable with length 256
heatmap(x, y, 10^9 .* (height - deformation))
This way each rectangle will have 1/256 unit width and 1/256 unit height. You may assign x and y to any other iterable so long as each of them contains 256 entries. You can even set them as arrays of strings.
You can set actual ticks using an iterator with xticks or yticks keyword arguments in a similar manner.

Related

how to set octave x-axis limitation and interval

I want to plot a graph in octave in which the x-axis maximum value is 2048, and the they start with 0 and increment by 100.
The y data is a vector of 2049 numbers.
here is my code :
ydata = load ("data.txt");
x = linspace(1,2048,2048);
plot(x,ydata(:,1));
this figures the x-axis with maximum value of 2500.
To add to Silver's answer, you might also want to set the XTick property of the axes:
ydata = rand(2048,1);
plot(ydata(:,1))
xlim([0 2048])
set(gca,'XTick',0:100:2048)
This produces the following, which I think is what you're after (note the axis labels are a bit on top of each other but that's because you wanted them every 100 - changing the aspect ratio of the figure will help):
I think what you are looking for is xlim
xlim([0 2048]);
That will limit the x-axes in the plot between 0 and 2048.
See the documentation here for more info.

R rgl 3d log scale plot and Antenna pattern plots

first of all before my sharing my problem I want to share a bit of code that might be helpful for some people outside there. I have been looking quite some time code to plot in 3d antenna measurements but I could not find code that does that. The problem is that antenna measurements have polar coordinates and typical 3d plot functions use cartesian coordinates. So my code below does just that (I am not an advanced programmer so I am sure someone might be able to optimize it for its use). The code can be run directly and I added comments to make it easier readable.
require("rgl")
require("fields")
degreeToRadian<-function(degree){
return (0.01745329252*degree)
}
turnPolarToX<-function(Amplitude,Coordinate){
return (Amplitude*cos(degreeToRadian(Coordinate)))
}
turnPolarToY<-function(Amplitude,Coordinate){
return (Amplitude*sin(degreeToRadian(Coordinate)))
}
# inputs for the code
test<-runif(359,min=-50,max=-20) # the 359 elements correspond to the polar coordinates of 1 to 359
test2<-runif(359,min=-50,max=-20) # the 359 elements correspond to the polar coordinates of 1 to 359
test3<-runif(359,min=-50,max=-20) # the 359 elements correspond to the polar coordinates of 1 to 359
# My three input vectors above are considered to be dBm values, typically unit for antenna or propagation measurements
# I want to plot those on three different 3d planes the XY, the YZ and the ZX. Since the rgl does not support
# polar coordinates I need to cast my polar coordinates to cartesian ones, using the three functions
# defined at the beginning. I also need to change my dBm values to their linear relative ones that are the mW
# Convert my dBm to linear ones
test<-10^(test/10)
test2<-10^(test2/10)
test3<-10^(test3/10)
# Start preparing the data to be plotted in cartesian domain
X1<-turnPolarToX(test,1:359)
Y1<-turnPolarToY(test,1:359)
Z1<-rep(0,359)
X2<-turnPolarToX(test2,1:359)
Y2<-rep(0,359)
Z2<-turnPolarToY(test2,1:359)
X3<-rep(0,359)
Y3<-turnPolarToX(test3,1:359)
Z3<-turnPolarToY(test3,1:359)
# Time for the plotting now
Min<-min(test,test2,test3)
Max<-max(test,test2,test3)
bgplot3d( suppressWarnings (
image.plot( legend.only=TRUE, legend.args=list(text='dBm/100kHz'), zlim=c(Min,Max),col=plotrix::color.scale(seq(Min,Max,length.out=21),c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)))
) # zlim is the colorbar numbers
)
# for below alternatively you can also use the lines3d to get values
points3d(X1,Y1,Z1,col=plotrix::color.scale(test,c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)),add=TRUE)
points3d(X2,Y2,Z2,col=plotrix::color.scale(test2,c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)),add=TRUE)
points3d(X3,Y3,Z3,col=plotrix::color.scale(test3,c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)),add=TRUE)
The problem I have now is that my plotting ideally I would like to be on a log scale that the rgl packet does not support! If I try to use log on my X,Y,Z to compress them I get an error that log is not defined for negative numbers (of course that is correct). How would you think to solve that problem on compressing the axes values when log scale plotting is not supported?
I would like to thank you for your reply
Regards
Alex
It doesn't make sense to apply a log scale to X, Y and Z. Just apply it to your original data, and transform the logged values to polar coordinates.
Since your logged test values are negative, you probably will want to apply an offset; polar coordinates with negative radius values are pretty hard to interpret.
Once you have done that, you can use the axis3d() function to add an axis with arbitrary labels to the plot. For example, if you want the origin to correspond to -50 dBm, you'd skip the transformation to linear coordinates and just add 50. You need to undo this when calculating labels. Here's your example, modified:
require("rgl")
require("fields")
degreeToRadian<-function(degree){
return (0.01745329252*degree)
}
turnPolarToX<-function(Amplitude,Coordinate){
return (Amplitude*cos(degreeToRadian(Coordinate)))
}
turnPolarToY<-function(Amplitude,Coordinate){
return (Amplitude*sin(degreeToRadian(Coordinate)))
}
# inputs for the code
test<-runif(359,min=-50,max=-20) # the 359 elements correspond to the polar coordinates of 1 to 359
test2<-runif(359,min=-50,max=-20) # the 359 elements correspond to the polar coordinates of 1 to 359
test3<-runif(359,min=-50,max=-20) # the 359 elements correspond to the polar coordinates of 1 to 359
# Add an offset of 50 to the values.
test <- test + 50
test2 <- test2 + 50
test3 <- test3 + 50
# Start preparing the data to be plotted in cartesian domain
X1<-turnPolarToX(test,1:359)
Y1<-turnPolarToY(test,1:359)
Z1<-rep(0,359)
X2<-turnPolarToX(test2,1:359)
Y2<-rep(0,359)
Z2<-turnPolarToY(test2,1:359)
X3<-rep(0,359)
Y3<-turnPolarToX(test3,1:359)
Z3<-turnPolarToY(test3,1:359)
# Time for the plotting now
Min<-min(test,test2,test3)
Max<-max(test,test2,test3)
bgplot3d( suppressWarnings (
image.plot( legend.only=TRUE, legend.args=list(text='dBm/100kHz'), zlim=c(Min,Max)-50,col=plotrix::color.scale(seq(Min-50,Max-50,length.out=21),c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)-50))
) # zlim is the colorbar numbers
)
# for below alternatively you can also use the lines3d to get values
points3d(X1,Y1,Z1,col=plotrix::color.scale(test,c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)),add=TRUE)
points3d(X2,Y2,Z2,col=plotrix::color.scale(test2,c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)),add=TRUE)
points3d(X3,Y3,Z3,col=plotrix::color.scale(test3,c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)),add=TRUE)
# Add axes
labels <- pretty(c(-50, -20))
axis3d("x", at = labels + 50, labels = labels, pos = c(NA, 0, 0) )
axis3d("y", at = labels + 50, labels = labels, pos = c(0, NA, 0) )
axis3d("z", at = labels + 50, labels = labels, pos = c(0, 0, NA) )
One my system it produces this display:
You might want to add circles to show how the scale continues around in each plane. This code would do it:
theta <- seq(0, 2*pi, len = 100)
for (i in seq_along(labels)) {
x <- (labels[i] + 50)*cos(theta)
y <- (labels[i] + 50)*sin(theta)
lines3d(x, y, 0)
lines3d(x, 0, y)
lines3d(0, x, y)
}
I find the plot too busy with those added, but you can try it and decide for yourself.

How to create exponential graph

How can I make an x-axis that doubles for every increment? I want equal distances between 0, 128, 256, 512, 1024 and 2048. How can I do that?
I'm trying to plot points from a benchmark where I measured time and doubled the memory size every increment.
You can cheat and plot with a linear axis, like from 1 up to as many numbers as you desire, then change the labels when you're done. You can use the 'xtick' property to set what horizontal tick values on your graph remain and the 'xticklabel' property to change the labels to your desired values.
labels = [0 128 256 512 1024 2048]; % Provide your labels here
x = 1 : numel(labels);
y = rand(1, numel(x)); % Insert your data here
plot(x, y, 'b.'); % Plot your data
set(gca, 'xtick', x); % Change the x-axis so only the right amount of ticks remain
set(gca, 'xticklabel', labels) % Change the labels to the desired ones
I get the following graph. Note that the data I'm plotting is completely random as I don't have your data but I want to demonstrate what the changed plot looks like:
For more properties that you can change on your graph, see the Axes Properties page on the Octave docs.
With apologies to Rayryeng, since I'm essentially proposing the same method at heart, but I felt it was missing important info, such as how to convert the axis itself to equally spaced intervals in the first place, without messing with the data. So here's a complete solution for example data X vs Y, producing the equivalent of semilogx for base 2.
Y = 1 : 10;
X = 2 .^ Y;
XTicks = log2(X);
XTickLabels = {};
for XTick = XTicks
XTickLabels{end+1} = sprintf('2^{%d}', XTick);
end
plot (log2 (X), Y);
set(gca, 'xtick', XTicks, 'xticklabel', XTickLabels);
Note that if you plan to 'superimpose' another plot on top of this, you'll have to take into account that the actual values in the X axis are essentially "1, 2, 3, ... 10", so either "log-ify" the new plot's X-axis values too, before superimposing via hold on, or plot onto another, independent set of axes entirely and place them in the same position.
Note: I have assumed that you're after a base-2 logarithmic x-axis. If you do actually want the 0-128 interval to be the same as the 128-256 interval, then modify as per Rayrengs answer --- or even better, use a more appropriate graph, like a bar graph! (i.e. with the 'powers-of-two' used purely as descriptive labels for each column)

How to get a pixel matrix from grayscale image in R?

When grayscale images are represented by matrices each element of the matrix determines the intensity of the corresponding pixel. For convenience, most of the current digital files use integer numbers between 0 (to indicate black, the color of minimal intensity) and 255 (to indicate white, maximum intensity), giving a total of 256 = 2^8 different levels of gray.
Is there a way to get a pixel matrix of graysale images in R whose pixel values will range from 0 to 255?
It will also be helpful to know if I can resize the images in preferred dimension (say, $28 \times 28$) in R and then convert them into a pixel matrix whose elements range from 0 to 255?
What happens if the original image is RGB but I want the matrix for grayscale?
The R package png offers the readPNG() function which can read raster graphics (consisting of "pixel matrices") in PNG format into R. It returns either a single matrix with gray values in [0, 1] or three matrices with the RGB values in [0, 1].
For transforming between [0, 1] and {0, ..., 255} simply multiply or divide with 255 and round, if desired.
For transforming between RGB and grayscale you can use for example the desaturate() function from the colorspace package.
As an example, let's download the image you suggested:
download.file("http://www.greenmountaindiapers.com/skin/common_files/modules/Socialize/images/twitter.png",
destfile = "twitter.png")
Then we load the packages mentioned above:
library("png")
library("colorspace")
First, we read the PNG image into an array x with dimension 28 x 28 x 4. Thus, the image has 28 x 28 pixels and four channels: red, green, blue and alpha (for semi-transparency).
x <- readPNG("twitter.png")
dim(x)
## [1] 28 28 4
Now we can transform this into various other formats: y is a vector of hex character strings, specifying colors in R. yg is the corresponding desaturated color (again as hex character) with grayscale only. yn is the numeric amount of gray. All three objects are arranged into 28 x 28 matrices at the end
y <- rgb(x[,,1], x[,,2], x[,,3], alpha = x[,,4])
yg <- desaturate(y)
yn <- col2rgb(yg)[1, ]/255
dim(y) <- dim(yg) <- dim(yn) <- dim(x)[1:2]
I hope that at least one of these versions is what you are looking for. To check the pixel matrices I have written a small convenience function for visualization:
pixmatplot <- function (x, ...) {
d <- dim(x)
xcoord <- t(expand.grid(1:d[1], 1:d[2]))
xcoord <- t(xcoord/d)
par(mar = rep(1, 4))
plot(0, 0, type = "n", xlab = "", ylab = "", axes = FALSE,
xlim = c(0, 1), ylim = c(0, 1), ...)
rect(xcoord[, 2L] - 1/d[2L], 1 - (xcoord[, 1L] - 1/d[1L]),
xcoord[, 2L], 1 - xcoord[, 1L], col = x, border = "transparent")
}
For illustration let's look at:
pixmatplot(y)
pixmatplot(yg)
If you have a larger image and want to bring it to 28 x 28, I would average the gray values from the corresponding rows/columns and insert the results into a matrix of the desired dimension.
Final note: While it is certainly possible to do all this in R, it might be more convenient to use an image manipulation software instead. Depending on what you aim at, it might be easier to just use ImageMagick's mogrify for example:
mogrify -resize 28 -type grayscale twitter.png
Here is an example of converting and drawing an image from a grayscale png. Please ensure installing the relevant packages first.
library(png)
library(RCurl)
myurl = "https://postgis.net/docs/manual-dev/images/apple_st_grayscale.png"
my_image = readPNG(getURLContent(myurl))
img_mat=my_image[,,1] # will hold the grayscale values divided by 255
img_mat=t(apply(img_mat, 2, rev)) # otherwise the image will be rotated
image(img_mat, col = gray((0:255)/255)) # plot in grayscale

How to determine symbol size in x and y units

I would like to know the approximate dimensions of symbol in my plot area. I think that par()$ps only really refers to text size. So how is a symbol size calculated using the cex parameter? For example, below is a plot of a single point of size cex=10. Can i determine its size from the plot devices par parameters?
plot(50, 50, ylim=c(0,100), xlim=c(0,100), cex=10)
#click on outer x limits
p1 <- locator(n=1,typ="n")
p2 <- locator(n=1,typ="n")
#approx width in x units(~15)
abs(p1$x - p2$x)
Thanks for you help. -Marc
According to the documentation contained in ?par, we have that,
cin - R.O.; character size (width, height) in inches. These are the same measurements as cra, expressed in different units.
cra - R.O.; size of default character (width, height) in ‘rasters’ (pixels). Some devices have no concept of pixels and so assume an arbitrary pixel size, usually 1/72 inch. These are the same measurements as cin, expressed in different units.
On my machine, these values appear to be:
par("cin")
[1] 0.15 0.20
> par("cra")
[1] 10.8 14.4
So character magnification via cex ought to happen relative to these dimensions, presumably by scaling the horizontal and vertical dimensions separately (although I don't know that for sure).

Resources