I want to plot data with octaves hist() function. Unfortunately, as the numbers of the x-axis are quite large, they are displayed in scientific format, for example like 2e+007.
As this is a bit hard to read, I'd like them to be dislayed only as exponentials to the base 10, without the product or the e. So just like 10^5 for example. How can I achieve this?
When I plot data with the loglog() function, it uses the scale as I need it by default, but not for the hist().
EDIT:
To be a bit more preceise, I add some code and a picture of my plot.
NUM_SAMPLES = 10000;
% Open file.
input = fopen(filename);
x = [];
for i=[1:NUM_SAMPLES]
line = fgetl(input);
data = strsplit(line, ';');
x(end + 1) = str2num(data{1,2})/(1000);
endfor
% Close file.
fclose(input);
% Plot histogram.
figure('Position',[0,0,700,500]);
hist(x, 500);
So I just read some big numbers from my file and want to plot it with hist. Because the numbers are big, the automatically get displayed in loc scale and scientific format. Here you can see an example plot:
Unfortunately set(gca(), 'xscale', 'log'); doesn't change anything, so I think this plot is also consider log scale, but just a bad number format.
You can set the xticklabel or yticklabel manually, for example:
x = [1e7, 1e8, 1e9];
ax = gca();
set(ax, 'xticklabel', {'0','2e8','4e8','6e8','8e8','10e8'});
hist(x);
Alternatively, you can set the x axis to be in log scale:
set(ax, 'xscale', 'log');
Related
Julia has the delightful ability to generate plots constructed from Unicode symbols which are printed directly to the command line in a very straightforward way. For example, the following code generates a Unicode plot of a sine function directly to the command line:
using Plots
unicodeplots();
x = [0:0.1:2*pi;];
y = sin.(x);
plot(x,y)
I would like to try to find a way to create an animated plot of this form directly on the command line. Ideally, I would like to generate a single plot in Unicode that is ``updated" in such a way that it appears animated.
However, although printing hundreds of distinct frames to the command line is naturally less appealing, such a solution is acceptable if it ``looks" like an animation. Another less acceptable solution is to print such Unicode plots into a gif in a way that is consistent for all platforms; attempts to do any of this involving jury-rigging #animate and #gif have largely failed, since either function cannot even print Unicode plots to a file in the Windows form of Julia.
UPDATE: Here is an example of code that generates an "animation" in the command line that is not really acceptable, which simply plots each distinct frame followed by "spacing" in the command line provided by a special Unicode character (tip provided by niczky12):
using Plots
unicodeplots();
n = 100;
x = [0:0.1:4*pi;];
for i = 1:30
y = sin.(x .+ (i/2));
plot(x, y, show=true, xlims = (0,4*pi), ylims = (-1,1))
sleep(0.01)
println("\33[2J")
end
A slight improvement might be this:
let
print("\33[2J")
for i in 1:30
println("\33[H")
y = sin.(x .+ (i/2));
plot(x, y, show=true, xlims = (0,4*pi), ylims = (-1,1))
sleep(0.01)
end
end
I am trying to create a plot in Octave (using v4.4.1 on Windows) using plotyy and putting the legend outside the plot (because the data covers all the usable space inside the graph). The following MVCE should reproduce the issue fairly well:
% Generate some random data to reproduce the issue
data = rand(1000,10);
data(:,1:8) = data(:,1:8)-0.5;
data(:,9:10) = data(:,9:10)+30;
timedate = linspace(737310,737313,size(data,1));
data_labels={'1';'2';'3';'4';'5';'6';'7';'8';'9';'10'};
% Plot the data
figure('Name','MVCE','Position',[300 200 1000 600])
[ax,h1,h2] = plotyy(timedate,data(:,1:8),timedate,data(:,9:10));
set(h2,'Visible','on');
datetick(ax(1),'x','HH:MM:SS')
datetick(ax(2),'x','HH:MM:SS')
ylim(ax(1),[-1 1])
ylim(ax(2),[20 50])
xlabel('Date & time')
ylabel(ax(1),'Something')
ylabel(ax(2),'Something else')
title('plotyy graph with legend problem')
[hl,hlo] = legend([h1;h2],data_labels,'location','eastoutside');
grid on
This the output of the code using the gnuplot graphics toolkit:
As you can see, the legend does not go outside the plot, and the second y axis is not visible (it looks like part of the plot is actually truncated).
I have tried using the qt and fltk graphics toolkits, which give issues of their own:
With qt graphics toolkit
With fltk graphics toolkit
Can anoybody suggest a fix or at least workaround? Does the same issue also happen in MATLAB or is it Octave-specific?
EDIT
Using the suggestion in Tasos' answer, I managed to almost make it work with gnuplot:
% Plot the data
figure('Name','MVCE','Position',[300 200 1000 600])
[ax,h1,h2] = plotyy(timedate,data(:,1:8),timedate,data(:,9:10));
set(h2,'Visible','on');
datetick(ax(1),'x','HH:MM:SS')
datetick(ax(2),'x','HH:MM:SS')
ylim(ax(1),[-1 1])
ylim(ax(2),[20 50])
ax1Pos = get(ax(1), 'position');
ax2Pos = get(ax(2), 'position');
ax1Pos(3) = ax1Pos(3) * 0.73;
ax2Pos(3) = ax2Pos(3) * 0.73;
set(ax(1), 'position', ax2Pos);
set(ax(2), 'position', ax2Pos);
xlabel('Date & time')
ylabel(ax(1),'Something')
ylabel(ax(2),'Something else')
title('plotyy graph with legend problem')
[hl,hlo] = legend([h1;h2],data_labels,'location','eastoutside');
pos = get(hl,'Position');
pos(1) = 0.9;
set(hl,'Position',pos)
grid on
Which produces:
Apart from the fact that the legend overlays with the second y axis label (which it doesn't on my screen, only when printing to jpg), the problem is that Octave appears to plot two legends on top of each other for some reason: one with the first set of data attached to the first set of axes, and one with the complete set of data, for both axes right on top of the first legend. This is obviously wrong, and trying to set the Visible property of hl to off deletes both legends, not just the one.
UPDATED: deals with both legend placement and OpenGL precision affecting graph.
Regarding the problem of the legend not appearing exactly in the position you want it to, you can manually adjust the position of all axes involved in a figure, to place them exactly where you want.
Regarding the problem of OpenGL being unable to deal with the precision involved when adding small numbers to a large number, plot the graph with only the small numbers involved, and then simply adjust the xticklabels to correspond to the numbers you desire.
Full code below:
% Generate some random data to reproduce the issue
data = rand(1000,10);
data(:,1:8) = data(:,1:8)-0.5;
data(:,9:10) = data(:,9:10)+30;
t_offset = 737310;
timedate = linspace(0,3,size(data,1));
data_labels={'1';'2';'3';'4';'5';'6';'7';'8';'9';'10'};
% Plot the data
figure('Name','MVCE','Position',[300 200 1000 600])
[ax,h1,h2] = plotyy(timedate,data(:,1:8),timedate,data(:,9:10));
set(h2,'Visible','on');
ylim(ax(1),[-1 1])
ylim(ax(2),[20 50])
ylabel(ax(1),'Something')
ylabel(ax(2),'Something else')
title('plotyy graph with legend problem')
[hl,hlo] = legend([h1;h2],data_labels,'location','eastoutside');
set(hl, 'position', get(hl, 'position') .* [0.975, 1, 0.975, 1] )
grid on
ax1Pos = get(ax(1), 'position'); ax2Pos = get(ax(2), 'position');
ax1Pos(3) = ax1Pos(3) * 0.95; ax2Pos(3) = ax2Pos(3) * 0.95;
set(ax(1), 'position', ax2Pos); set(ax(2), 'position', ax2Pos);
XTicks = get(ax(1), 'xtick');
set(ax(1), 'xticklabel', datestr(XTicks + t_offset, 'HH:MM:SS'))
xlabel('Date & time')
set(ax(2), 'xtick', []);
Output:
currently I am plotting 2000 some lines on a single plot in r. I am using the data from a spreadsheet which i cannot disclose due to sensitive information, but I'll try to illistrate how it is arranged.
x1/x1/x1/x1/x1/x1/etc.
y1/y1/y1/y1/y1/y1/etc.
x2/x2/x2/x2/x2/x2/etc.
y2/y2/y2/y2/y2/y2/etc.
...
x4436/x4436/x4436/etc.
y4436/y4436/y4436/etc.
where each x1,y1 is a point on a separate line. I need to plot a point on the endpoint of each line and I cannot seem to get my code to work. Currently I am using this to generate the points:
for (k in (1:2218)*2) {
q <- unlist(e_web_clear[2*k])
w <- unlist(e_web_clear[716])
points(w, q, col = "lightblue")
}
the way I imagined it, it would loop back to each point in every other row, to get only the y value for each line, and it would take the values from only the last column of my data (column 716).
needless to say, it did not work as intended, any suggestions?
EDIT:
spreadsheet with just a small portion of values here
and the code used to generate the lines:
for (j in (1:2218)*2) {
x <- unlist(e_web_clear[2*j-1,])
y <- unlist(e_web_clear[2*j,])
lines(x,y,'l',lwd=.00000000001, col="black")
}
data was imported as text file
Edit2:
this is the graph i am getting.
the graph i want to get would have the endpoint of each line highlighted in light blue. i believe it should look something like this. http: / /imgur.com/13b9MZL
figured it out.
I edited my line loop to place a point on the last vector point of each line.
for (j in (1:2218)*2) {
x <- unlist(e_web_clear[2*j-1,])
y <- unlist(e_web_clear[2*j,])
lines(x,y,'l',lwd=.00000000001, col="black")
points(x[358], y[358], lwd = 1.5, cex = .1, col = "lightblue")
}
I have a data.matrix that is approximately 4000 rows and 100 columns. I am doing a heatmap of the data like:
data<-heatmap(data_matrix,Rowv=NA,Colv=NA,col=cm.colors(256),scale="column",margins=c(5,10))
But the problem that I got is that the labels that appear in the column are too grouped, so it is impossible to visualize them correctly. How I can resize the heatmap so I can see the values of the labels of the column? I tried to print it in pdf, but it only appears a black stripe.
Thanks
I am including a figure of the heatmap, the portion that I want to see are the labels that are in the right part, but they are too close together.
First of all it's better to put your output directly to a PDF file - you may use other image formats but PDF is the best because it is a vector output and you can zoom as much as you want:
pdf("Your-file.pdf", paper="a4", width=8, height=8)
Then it's better to use pheatmap( = pretty heatmap) package. It makes really better heatmaps with a color key besides your heatmap. Finally although the pheatmap() function tries to reduce the label size while you have many rows, but it fails for really large number of rows. So I use the code below for really high - but not too high - number of rows:
library(pheatmap)
library(gplots)
if (nrow(table) > 100) stop("Too many rows for heatmap, who can read?!")
fontsize_row = 10 - nrow(table) / 15
pheatmap(table, col=greenred(256), main="My Heatmap", cluster_cols=F,
fontsize_row=fontsize_row, border_color=NA)
You may change fontsize_col for the column labels. You have many interesting options like display_numbers to have the values inside the cells of your heatmap. Just read ?pheatmap.
This is an example generated by the default parameters of pheatmap() command:
Finally note that too many rows are easy to read on a display, but useless for print.
In Rstudio you can easily resize the graphic window, same holds for Rgui. Alternatively, if you save the plot to file you can use a bigger size for your graphics, e.g. bigger width and height when calling pdf or png.
You can use cexRow = and cexCol =.
You can get more information into ??heatmap.2
# Row/Column Labeling
margins = c(5, 5),
ColSideColors,
RowSideColors,
cexRow = 0.2 + 1/log10(nr),
cexCol = 0.2 + 1/log10(nc),
labRow = NULL,
labCol = NULL,
srtRow = NULL,
srtCol = NULL,
adjRow = c(0,NA),
adjCol = c(NA,0),
offsetRow = 0.5,
offsetCol = 0.5,
colRow = NULL,
colCol = NULL
If you use pheatmap (https://www.rdocumentation.org/packages/COMPASS/versions/1.10.2/topics/pheatmap) you can spread out those labels by adjusting the cellheight parameter.
If you are doing this in R notebook, even though the entire heat map will not display in your output window when you run the code, when you save the heat map to your computer using the filename parameter, pheatmap will automatically calculate the optimal size for the output file so that your entire heatmap will be displayed in your output file. If this size is not to your liking you can adjust using width and height parameters, but it is unlikely you will want to do this.
I need to draw lines from the data stored in a text file.
So far I am able only to draw points on a graph and i would like to have them as lines (line graph).
Here's the code:
pupil_data <- read.table("C:/a1t_left_test.dat", header=T, sep="\t")
max_y <- max(pupil_data$PupilLeft)
plot(NA,NA,xlim=c(0,length(pupil_data$PupilLeft)), ylim=c(2,max_y));
for (i in 1:(length(pupil_data$PupilLeft) - 1))
{
points(i, y = pupil_data$PupilLeft[i], type = "o", col = "red", cex = 0.5, lwd = 2.0)
}
Please help me change this line of code:
points(i, y = pupil_data$PupilLeft[i], type = "o", col = "red")
to draw lines from the data.
Here is the data in the file:
PupilLeft
3.553479
3.539469
3.527239
3.613131
3.649437
3.632779
3.614373
3.605981
3.595985
3.630766
3.590724
3.626535
3.62386
3.619688
3.595711
3.627841
3.623596
3.650569
3.64876
By default, R will plot a single vector as the y coordinates, and use a sequence for the x coordinates. So to make the plot you are after, all you need is:
plot(pupil_data$PupilLeft, type = "o")
You haven't provided any example data, but you can see this with the built-in iris data set:
plot(iris[,1], type = "o")
This does in fact plot the points as lines. If you are actually getting points without lines, you'll need to provide a working example with your data to figure out why.
EDIT:
Your original code doesn't work because of the loop. You are in effect asking R to plot a line connecting a single point to itself each time through the loop. The next time through the loop R doesn't know that there are other points that you want connected; if it did, this would break the intended use of points, which is to add points/lines to an existing plot.
Of course, the line connecting a point to itself doesn't really make sense, and so it isn't plotted (or is plotted too small to see, same result).
Your example is most easily done without a loop:
PupilLeft <- c(3.553479 ,3.539469 ,3.527239 ,3.613131 ,3.649437 ,3.632779 ,3.614373
,3.605981 ,3.595985 ,3.630766 ,3.590724 ,3.626535 ,3.62386 ,3.619688
,3.595711 ,3.627841 ,3.623596 ,3.650569 ,3.64876)
plot(PupilLeft, type = 'o')
If you really do need to use a loop, then the coding becomes more involved. One approach would be to use a closure:
makeaddpoint <- function(firstpoint){
## firstpoint is the y value of the first point in the series
lastpt <- firstpoint
lastptind <- 1
addpoint <- function(nextpt, ...){
pts <- rbind(c(lastptind, lastpt), c(lastptind + 1, nextpt))
points(pts, ... )
lastpt <<- nextpt
lastptind <<- lastptind + 1
}
return(addpoint)
}
myaddpoint <- makeaddpoint(PupilLeft[1])
plot(NA,NA,xlim=c(0,length(PupilLeft)), ylim=c(2,max(PupilLeft)))
for (i in 2:(length(PupilLeft)))
{
myaddpoint(PupilLeft[i], type = "o")
}
You can then wrap the myaddpoint call in the for loop with whatever testing you need to decide whether or not you will actually plot that point. The function returned by makeaddpoint will keep track of the plot indexing for you.
This is normal programming for Lisp-like languages. If you find it confusing you can do this without a closure, but you'll need to handle incrementing the index and storing the previous point value 'manually' in your loop.
There is a strong aversion among experienced R coders to using for-loops when not really needed. This is an example of a loop-less use of a vectorized function named segments that takes 4 vectors as arguments: x0,y0, x1,y1
npups <-length(pupil_data$PupilLeft)
segments(1:(npups-1), pupil_data$PupilLeft[-npups], # the starting points
2:npups, pupil_data$PupilLeft[-1] ) # the ending points