Line increment in gnuplot - sed

I have large files (~5 Gbs) whit constant increment on x-axis, let's say each dt.
I would like to know if I could set the every command of Gnuplot as logarithmic increment not linear.
plot "fileA.txt" u 1:2 every dt #linear increment of dt
This is because, if x-axis is in log-scale, then I want to have more points for low values of x in (10^-4,10^-2) but also not an oversampling in (10^4,10^2) range. Somehow a differential increment.
Does I have to use external programs like sed to re-write my file first?
A test plot is included as well as the data. In blue the full data, in red the ones with the every command. As you can see one loose the information for short x also oversample the plot for large x. the data file
Many thanks.

You could plot smoothed data with points:
set key left
set logscale x
set yrange [3.9:4.8]
set samples 30
set terminal png
set output "log.png"
plot "fort.11" title "raw" with points lc 3 pointtype 5 pointsize 2,\
"" title "smooth" smooth csplines with points lc 1 pointtype 5 pointsize 1
set samples 30 tells gnuplot to use 30 points equidistant in x
smooth csplines interpolates the datapoints
with points plots with points instead of lines, which would be the default
Note that this does not plot the original data, and that smooth csplines introduces new points if the original datapoints are too far apart. This might or might not be what you want.

Related

How to set matlab xticks equal distance with unequal numerical spaces?

I am plotting data which is polynomial but I would like to show it on a straight line so that it is clearer.
I want the x-axis tick marks to show N^2 where N is the tick location. I also want the actual ticks on the graph to be evenly spaced even though the numbers aren't.
I tried to change the ticks using
xtick_squared = (0:10:100).^2
set(gca,'xTick',xtick_squared,'xTickLabel',xtick_squared)
but it gives this
How can I display them each being even spaced while reatining their values as well as adjusting the data?
This should work fine:
x = 0:10:100;
y = (x .^ 2) + 5;
labs = sprintfc('%d',x.^2);
plot(x,y);
set(gca,'XTickLabel',labs);
Actually, it's all about changing the tick labels without changing the ticks themselves. Here is the final output:
You can specify the location of x-ticks and then rename them.
Here is the code example:
x=[0,10,20,30,40,50].^2;
plot(x,x)
set(gca,'XTick',linspace(0,2500,6),'XTickLabels',num2cell(x))
P.S.: Note, that your actual data is plotted on evenly spaced grid. I've just renamed the ticks' names.
Edit: if you want to plot your actual data, you need to scale x-axis correspondingly. If you want to plot(x,x) you need to call plot(sqrt(x),x) instead:
x=[0,10,20,30,40,50].^2;
plot(sqrt(x),x)
set(gca,'XTick',linspace(0,2500,6),'XTickLabels',num2cell(x))

How to make a heat map on top of worldmap using hist3 in MATLAB?

My x-axis is latitudes, y-axis is longitudes, and z-axis is the hist3 of the two. It is given by: z=hist3(location(:,1:2),[180,360]), where location(:,1) is the latitude column, and location(:,2) is the longitude column.
What I now want is, instead of plotting on a self-created XY plane, I want to plot the same on a worldmap. And instead of representing the frequency of each latitude-longitude pair with the height of the bars of hist3, I want to represent the frequency of each location by a heat map on top of the world map, corresponding to each latitude-longitude pair's frequency on the dataset. I have been searching a lot for this, but have not found much help. How to do this? I could only plot the skeleton of the worldmap like this:
worldmap world
load geoid
geoshow(geoid, geoidrefvec, 'DisplayType', 'texturemap');
load coast
geoshow(lat, long)
I don't know what the colour is being produced based on.
Additionally, if possible, I would also like to know how to plot the hist3 on a 3D map of the world (or globe), where each bar of the hist3 would correspond to the frequency of each location (i.e., each latitude-longitude pair). Thank you.
The hist3 documentation, which you can find here hist3, says:
Color the bars based on the frequency of the observations, i.e. according to the height of the bars. set(get(gca,'child'),'FaceColor','interp','CDataMode','auto');
If that's not what you need, you might wanna try it with colormap. More info about it here colormap. I haven't tried using colormap on histograms directly, so If colormap doesn't help, then you can try creating a new matrix manually which will have values in colors instead of the Z values the histogram originally had.
To do that, you need to first calculate the maximum Z value with:
maxZ=max(Z);
Then, you need to calculate how much of the colors should overlap. For example, if you use RGB system and you assign Blue for the lowest values of the histogram, then Green for the middle and Red for the High, and the green starts after the Blue with no overlap, than it will look artificial. So, if you decide that you will have, for example overlapping of 10 values, than, having in mind that every R, G and B component of the RGB color images have 255 values (8 bits) and 10 of each overlap with the former, that means that you will have 255 values (from the Blue) + 245 values (From the Green, which is 255 - 10 since 10 of the Green overlap with those of the Blue) + 245 (From the Red, with the same comment as for the Green), which is total amount of 745 values that you can assign to the new colored Histogram.
If 745 > maxZ there is no logic for you to map the new Z with more than maxZ values. Then you can calculate the number of overlaping values in this manner:
if 745 > maxZ
overlap=floor(255- (maxZ-255)/2)
end
At this point you have 10 overlapping values (or more if you still think that it doesn't looks good) if the maximum value of the Z is bigger than the total amount of values you are trying to assign to the new Z, or overlap overlapping values, if the maximum of Z is smaller.
When you have this two numbers (i.e. 745 and maxZ), you can write the following code so you can create the newZ.
First you need to specify that newZ is of the same size as Z. You can achieve that by creating a zero matrix with the same size as Z, but having in mind that in order to be in color, it has to have an additional dimension, which will specify the three color components (if you are working with RGB).
This can be achieved in the following manner:
newZ=zeros(size(Z),3)
The number 3 is here, as I said, so you would be able to give color to the new histogram.
Now you need to calculate the step (this is needed only if maxZ > The number of colors you wish to assign). The step can be calculated as:
stepZ=maxZ/Total_Number_of_Colors
If maxZ is, for example 2000 and Total_Number_of_Colors is (With 10 overlaping colours) 745, then stepZ=2.6845637583892617449664429530201. You will also need a counter so you would know what color you would assign to the new matrix. You can initialize it here:
count=0;
Now, finally the assignment is as follows:
For i=1:stepZ:maxZ
count=count+1;
If count>245
NewZ(Z==stepz,3)=count;
elseif count>245 && count<256
NewZ(Z==stepz,3)=count;
NewZ(Z==stepz,2)=count-245;
elseif count>255
NewZ(Z==stepz,2)=count-245;
elseif count>500 && count<511
NewZ(Z==stepz,2)=count-245;
NewZ(Z==stepz,1)=count-500;
else
NewZ(Z==stepz,1)=count-500;
end
end
At this point you have colored your histogram. Note that you can manually color it in different colors than red, green and blue (even if you are working in RGB), but it would be a bit harder, so if you don't like the colors you can experiment with the last bit of code (the one with the for loops), or check the internet of some other automatic way to color your newZ matrix.
Now, how do you think to superimpose this matrix (histogram) over your map? Do you want only the black lines to be shown over the colored histogram? If that's the case, than it can be achieved by resampling the NewZ matrix (the colored histogram) with the same precision as the map. For example, if the map is of size MxN, then the histogram needs to be adjusted to that size. If, on the other hand, their sizes are the same, then you can directly continue to the next part.
Your job is to find all pixels that have black in the map. Since the map is not binary (blacks and whites), it will be a bit more harder, but still achievable. You need to find a satisfactory threshold for the three components. All the lines under this threshold should be the black lines that are shown on the map. You can test these values with imshow(worldmap) and checking the values of the black lines you wish to preserve (borders and land edges, for example) by pointing the cross tool on the top of the figure, in the tools bar on every pixel which is of interest.
You don't need to test all black lines that you wish to preserve. You just need to have some basic info about what values the threshold should have. Then you continue with the rest of the code and if you don't like the result so much, you just adjust the threshold in some trial and error manner. When you have figured that this threshold is, for example, (40, 30, 60) for all of the RGB values of the map that you wish to preserve (have in mind that only values that are between (0,0,0) and (40,30,60) will be kept this way, all others will be erased), then you can add the black lines with the following few commands:
for i = 1:size(worldmap,1)
for j = 1:size(worldmap,2)
if worldmap(i,j,1)<40 && worldmap(i,j,2)<30 && worldmap(i,j,3)<60
newZ(i,j,:)=worldmap(i,j,:)
end
end
I want to note that I haven't tested this code, since I don't have Matlab near me atm, so It can have few errors, but those should be easily debugable.
Hopes this is what you need,
Cheers!

plotting a text file with 4 columns in matlab

I want to plot a text file with 4 columns that first column in longitude,second in latitude, third is depth and forth is amount of displacement in each point.(it's related to a fualt)
-114.903874 41.207504 1.446784 2.323745
I want a plot to show the amount of displacement in each point (like images that we plot with imagesc),unfortunately "imagesc" command doesn't work for it.
how can I plot it?
Thanks for your attention
A simple way would be to use scatter3 and assign your displacements to be the colours. Note that you have to supply a size for this to work - I'm using [] (empty matrix) which will set it to default. If your four sets of values are four vectors of the same size, then it's just something like:
scatter3(lat,lon,depth,[],displacement, 'filled')
Values in displacement will be linearly mapped to the current colormap. 'filled' gives you filled markers rather than open ones (default marker is a circle but can be changed).
You can plot each point using plot3(longitude,latitude,depth). You can color each point according to the displacement in a for loop. The easiest way to do this is create a colormap, e.g. using jet and chosing the color according to the displacement.
figure;
hold on;
cmap = jet(256);
dispRange = [min(displacement),max(displacement)];
for k=1:size(longitude,2)
c = cmap(1+round(size(cmap,1)*(displacement(k)-dispRange(1))/dispRange(2)),:);
plot3(longitude(k),latitude(k),depth(k),'o', ...
'MarkerEdgeColor',c,'MarkerFaceColor',c);
end

MATLAB: Density-time Plot

I have 11 1x50 matrices that contain densities. The first looks like [20, 20, 20... 20] and represents time=0. The second looks like [20, 19, 22,..], etc. and represents time=100. These continue to vary until t=1000.
What I'm hoping to do is to create a plot with the elements' position on the x-axis (50 positions for the 50 pieces of data in each) and time (0-1000) on the y-axis. Ideally, I'd like the plot to be completely filled in with color densities, and a colorbar on the side that shows what densities the color range represents.
Any help would be greatly appreciated!
Sort of inspired by: http://www.chrisstucchio.com/blog/2012/dont_use_scatterplots.html
Assuming you have (or can arrange to have) all those vectors as columns of a 11x50 matrix:
A = randi(100, 11,50); %//example data
you can just use
imagesc(1:50, 0:100:1000, A)
colorbar
axis xy %// y axis increasing, not decreasing
Example:
Looking at the comments, it will be easier to stack these vectors into a 2D matrix. You have 11 individually named vectors. Assuming that your vectors are named vec1, vec2, vec3, etc., create a 2D matrix A that stacks these vectors on top of each other. Also, you'll need to include an extra row and column at the end of this matrix that contains the minimum over all of your vectors. The reason why this is will be apparent later, but for now take my word for it as this is what you need.
In other words:
A = [vec1; vec2; vec3; vec4; vec5; vec6; vec7; vec8; ...
vec9; vec10; vec11];
minA = min(A(:));
A = [A minA*ones(11,1); minA*ones(1,51)];
As such, the first row contains the information at time 0, the next row contains information at time 100, etc. up to time 1000.
Now that we have that finished, we can use the pcolor function to plot this data for you. pcolor stands for pseudo-coloured checkerboard plot. You call this by doing:
pcolor(A);
This will take a matrix stored in A and produce a checkerboard plot of your data. Each point in your matrix gets assigned a colour. The colours get automatically mapped so that the least value gets mapped to the lowest colour while the highest value gets mapped to the highest colour. pcolor does not plot the last row and last column of the matrix, but pcolor does use all of the data in the matrix. In order to ensure that the colours get properly mapped, we need to pad your matrix so that the last row and last column get assigned to the smallest value over all of your vectors. As you want to plot all values in the matrix, that's why we did what we did above.
Once we do this, we'll need to modify the X and Y ticks so that it conforms to your data. As such:
pcolor(A);
set(gca, 'XTick', 0.5:5:51.5);
set(gca, 'XTickLabel', 0:5:50);
set(gca, 'YTick', 1.5:11.5);
set(gca, 'YTickLabel', 0:100:1000);
xlabel('Sample Number');
ylabel('Time');
colorbar;
What the code does above is that it generates a checkerboard pattern like what we talked about. This labels the Sample Number on the x axis while time is on the y axis. You'll see with the two set commands that I did, this is a bit of a hack. The y axis by default labeled the ticks going from 1 - 12. What I did was that I changed these labels so that they go from 0 to 1000 in steps of 100 instead and I also removed the tick of 12. In addition, I have made sure that these labels go in the middle of each row. I do this by setting the YTick property so that I add 0.5 to each value going from 1 - 11. Once I do this, I then change the labels so that they go from 0 - 1000 in steps of 100. I also do the same for the x axis in a similar fashion to the y axis. I then add a colorbar to the side as per your request.
Following the above code, and generating random integer data that is between 13 and 27 as per your comments:
A = randi([13,27], 11, 50);
minA = min(A(:));
A = [A minA*ones(11,1); minA*ones(1,51)];
We get:
Obviously, the limits of the colour bar will change depending on the dynamic range of your data. I used randi and generated random integers within the range of 13 to 27. When you use this code for your purposes, the range of the colour bar will change depending on the dynamic range of your data, but the colours will be adjusted accordingly.
Good luck!

translate matlab plot to gnuplot 3d

I have a matrix of fft data over time, 8192 rows of data x 600 columns of time. The first column is a frequency label, the first row is shown below but doesn't actually exist in the data file, neither do the spaces, they are shown just for ease of reading.
Frequency, Sec1, Sec2, Sec3...Sec600
1e8, -95, -90, -92
1.1e8, -100, -101, -103
...
It is plotted in matlab with the following code (Apologies to other posters, I grabbed the wrong matlab code)
x is a matrix of 8192 rows by 600 columns, f is an array of frequency labels, FrameLength = 1, figN = 3
function [] = TimeFreq(x,f,FrameLength,figN)
[t,fftSize] = size(x);
t = (1:1:t) * FrameLength;
figure(figN);
mesh(f,t,x)
xlabel('Frequency, Hz')
ylabel('time, sec')
zlabel('Power, dBm')
title('Time-Freq Representation')
I cant quite figure out how to make it work in gnuplot. Here is a sample image of what it looks like in Matlab: http://imagebin.org/253633
To make this work in gnuplot, you'll want to take a look at the splot (for "surface plot") command. You can probably figure out quite a lot about it just by running the following commands in your terminal:
$ gnuplot
gnuplot> help splot
Specifically, you want to read the help page shown by running (after the above, when the prompt asks for a subtopic): datafile. That should tell you enough to get you started.
Also, the answers to this question might be helpful.
so here is the gnuplot command script that I ended up using. It has some additional elements in it that weren't in the original matlab plot but all the essentials are there.
set term png size 1900,1080
set datafile separator ","
set pm3d
# reverse our records so that time moves away from our perspective of the chart
set xrange[*:*] reverse
# hide parts of the chart that would make the 3d view look funny
set hidden3d
# slightly roate our perspective and compress the z axis
set view 45,75,,0.85
set palette defined (-120 "yellow", -70 "red", -30 "blue")
set grid x y z
set xlabel "time (secs)"
set ylabel "frequency"
set zlabel "dBm"
# plot all the data
set output waterfall.png
splot 'waterfall.csv' nonuniform matrix using 1:2:3 with pm3d lc palette