plotting 3D bar graph in matlab or excel - excel
I need to plot a 3D bar graph in matlab or excel. I am going to use some dates in x-axis, time in y-axis and some amount on the z-axis. Each record in csv file looks like ...
18-Apr, 21, 139.45
I am not sure how to do this right. can anyone help me please. I tried using pivort chart of excel. however, i could not manipulate the axis and use appropriate space between each tick.
thanks
kaisar
Since the question is lacking details, let me illustrate with an example.
Consider the following code:
%# read file contents: date,time,value
fid = fopen('data.csv','rt');
C = textscan(fid, '%s %s %f', 'Delimiter',',');
fclose(fid);
%# correctly reshape the data, and extract x/y labels
num = 5;
d = reshape(C{1},num,[]); d = d(1,:);
t = reshape(C{2},num,[]); t = t(:,1);
Z = reshape(C{3},num,[]);
%# plot 3D bars
bar3(Z)
xlabel('date'), ylabel('time'), zlabel('value')
set(gca, 'XTickLabel',d, 'YTickLabel',t)
I ran on the following data file:
data.csv
18-Apr,00:00,0.85535
18-Apr,03:00,0.38287
18-Apr,06:00,0.084649
18-Apr,09:00,0.73387
18-Apr,12:00,0.33199
19-Apr,00:00,0.83975
19-Apr,03:00,0.37172
19-Apr,06:00,0.82822
19-Apr,09:00,0.17652
19-Apr,12:00,0.12952
20-Apr,00:00,0.87988
20-Apr,03:00,0.044079
20-Apr,06:00,0.68672
20-Apr,09:00,0.73377
20-Apr,12:00,0.43717
21-Apr,00:00,0.37984
21-Apr,03:00,0.97966
21-Apr,06:00,0.39899
21-Apr,09:00,0.44019
21-Apr,12:00,0.15681
22-Apr,00:00,0.32603
22-Apr,03:00,0.31406
22-Apr,06:00,0.8945
22-Apr,09:00,0.24702
22-Apr,12:00,0.31068
23-Apr,00:00,0.40887
23-Apr,03:00,0.70801
23-Apr,06:00,0.14364
23-Apr,09:00,0.87132
23-Apr,12:00,0.083156
24-Apr,00:00,0.46174
24-Apr,03:00,0.030389
24-Apr,06:00,0.7532
24-Apr,09:00,0.70004
24-Apr,12:00,0.21451
25-Apr,00:00,0.6799
25-Apr,03:00,0.55729
25-Apr,06:00,0.85068
25-Apr,09:00,0.55857
25-Apr,12:00,0.90177
26-Apr,00:00,0.41952
26-Apr,03:00,0.35813
26-Apr,06:00,0.48899
26-Apr,09:00,0.25596
26-Apr,12:00,0.92917
27-Apr,00:00,0.46676
27-Apr,03:00,0.25401
27-Apr,06:00,0.43122
27-Apr,09:00,0.70253
27-Apr,12:00,0.40233
Use MATLAB's CSV reading functions (or write your own) and then use bar3 to display the data.
Related
Adding/multiplying heatmaps in gnuplot
Is it possible with gnuplot to perform an operation on data (adding/multiplying) from two data files to generate a heatmap with the result of the operation ? Ex: I have two files each with 4 columns, where Col1: X coordinate Col2: Y coordiante Col3: Value Col4: Uncertainty I want to multiply the columns 3 of each file. I wondered if something similar exists/would work in gnuplot, like ... splot 'first.dat' using 1:2:(v=$3), 'second.dat' using 1:2:(v*$3) I have been able to do this with two columns from the same file splot 'first.dat' using 1:2:($3*$4)
A very similar question has already been answered: gnuplot plot data from two files In your case it will look like that: splot "<paste first.dat second.dat" u 1:2:($3*$6) Note that all columns from both files are present, therefore you have to "skip" the ones from the second file.
The OP apparently runs Linux or MacOS. #Eldrad's nice and short solution won't work with Windows. Of course, you can install additional programs like gnuwin, awk, etc... A platform independent and gnuplot-only (bit more complicated) solution is the following. You load the files 1:1 into datablocks and print these datablocks into a new datablock by appending each line. Assumption is of course that the two files have the same number of lines. Code: ### plot data from different files combined with mathematical operation # platform independent gnuplot-only solution reset session Windows = GPVAL_SYSNAME[:7] eq "Windows" ? 1 : 0 # otherwise Linux or MacOS FILE = "first.dat" Data = "$Data1" if (Windows) { load '< echo '.Data.' ^<^<EOD & type "'.FILE.'"' } else { load '< echo "\'.Data.' <<EOD" & cat "'.FILE.'"' } FILE = "second.dat" Data = "$Data2" if (Windows) { load '< echo '.Data.' ^<^<EOD & type "'.FILE.'"' } else { load '< echo "\'.Data.' <<EOD" & cat "'.FILE.'"' } set print $Data do for [i=1:|$Data1|] { print $Data1[i][1:strlen($Data1[i])-1]."\t".$Data2[i] } set print splot $Data u 1:2:($3*$6) ### end of code
How to draw a horizontal line at the large y-axis integer?
For the following data.dat file: 08:01:59 451206975237005878 08:04:07 451207335040839108 08:05:56 451207643872368805 08:07:49 451207961547842270 08:09:56 451208317883903787 08:10:12 451208364811411904 08:14:09 451209030026853864 08:16:19 451209395116787156 08:17:14 451209552481002386 08:20:22 451210080432357203 08:25:36 451210963309583903 08:30:23 451211772783766177 08:34:04 451212394854723707 08:35:53 451212702239472024 08:48:46 451214876715294857 08:49:56 451215072475511660 08:51:24 451215321890488523 08:52:39 451215533925588479 08:52:42 451215542324801784 08:54:30 451215845971562410 08:55:08 451215951262906948 08:58:30 451216519498960432 I'd like to draw a horizontal line at the specific level (e.g. 451211772783766177). However, the number is too large to process. Here is my attempt (based on this post): $ gnuplot -p -e 'set arrow from 451211772783766177 to 451211772783766177; plot "data.dat" using 2 with lines' which gives the following error: line 0: warning: integer overflow; changing to floating point How I should proceed?
I would treat your large number as a constant function, and plot it right after your data. Also, writing it on a exponential notation X.XE+YY = X.X times 10 to the +YY power (more info on format specifiers here) also takes care of the error: plot "data.dat" using 2 with lines, 4.51211772783766177E17 with lines Let me know if this works!
Calculate the average of Spearman correlation
I have 2 columns A and B which contain the Spearman's correlation values as follows: 0.127272727 -0.260606061 -0.090909091 -0.224242424 0.345454545 0.745454545 0.478787879 0.660606061 -0.345454545 -0.333333333 0.151515152 -0.127272727 0.478787879 0.660606061 -0.321212121 -0.284848485 0.284848485 0.515151515 0.36969697 -0.139393939 -0.284848485 0.272727273 How can I calculate the average of those correlation values in these 2 columns in Excel or Matlab ? I found a close answer in this link : https://stats.stackexchange.com/questions/8019/averaging-correlation-values The main point is we can not use mean or average in this case, as explained in the link. They proposed a nice way to do that, but I dont know how to implement it in Excel or Matlab.
Following the second answer of the link you provided, which is the most general case, you can calculate the average Spearman's rho in Matlab as follows: M = [0.127272727 -0.260606061; -0.090909091 -0.224242424; 0.345454545 0.745454545; 0.478787879 0.660606061; -0.345454545 -0.333333333; 0.151515152 -0.127272727; 0.478787879 0.660606061; -0.321212121 -0.284848485; 0.284848485 0.515151515; 0.36969697 -0.139393939; -0.284848485 0.272727273]; z = atanh(M); meanRho = tanh(mean(z)); As you can see it gives mean values of meanRho = 0.1165 0.1796 whereas the simple mean is quite close: mean(M) ans = 0.1085 0.1350 Edit: more information on Fisher's transformation here.
In MATLAB, define a matrix with these values and use mean function as follows: %define a matrix M M = [0.127272727 -0.260606061; -0.090909091 -0.224242424; 0.345454545 0.745454545; 0.478787879 0.660606061; -0.345454545 -0.333333333; 0.151515152 -0.127272727; 0.478787879 0.660606061; -0.321212121 -0.284848485; 0.284848485 0.515151515; 0.36969697 -0.139393939; -0.284848485 0.272727273]; %calculates the mean of each column meanVals = mean(M); Result meanVals = 0.1085 0.1350 It is also possible to calculate the total meanm and the mean of each row as follows: meanVals = mean(M); %total mean meanVals = mean(M,2); %mean of each row
Use matlab to search excel data file for time range and copy data into variable
In my excel file I have a time column in 12 hr clock time and a bunch of data columns. I have pasted a snippet of it in this post as a code since i cant attach a file. I am trying to build a gui that will take an input from the user like so: start time: 7:29:32 AM End time: 7:29:51 AM Then do the following: calculate the time that has passed in seconds (should be just a row count, data is gathered once a second) copy the data in the time range from the "Data 3" column in to a variable perform other calculations on the data copied as needed I am having some trouble figuring out what to do to search the time data and find its location since it imports as text with xlsread. any ideas? The data looks like this: Time Data 1 Data 2 Data 3 Data 4 Data 5 7:29:25 AM 0.878556385 0.388400561 0.076890401 0.93335277 0.884750618 7:29:26 AM 0.695838393 0.712762566 0.014814069 0.81264949 0.450303694 7:29:27 AM 0.250846937 0.508617941 0.24802015 0.722457624 0.47119616 7:29:28 AM 0.206189924 0.82970364 0.819163787 0.060932817 0.73455323 7:29:29 AM 0.161844331 0.768214077 0.154097877 0.988201094 0.951520263 7:29:30 AM 0.704242494 0.371877481 0.944482485 0.79207359 0.57390951 7:29:31 AM 0.072028024 0.120263127 0.577396985 0.694153791 0.341824004 7:29:32 AM 0.241817775 0.32573323 0.484644494 0.377938298 0.090122672 7:29:33 AM 0.500962945 0.540808907 0.582958676 0.043377373 0.041274613 7:29:34 AM 0.087742217 0.596508236 0.020250297 0.926901109 0.45960323 7:29:35 AM 0.268222071 0.291034947 0.598887588 0.575571111 0.136424853 7:29:36 AM 0.42880255 0.349597405 0.936733938 0.232128788 0.555528823 7:29:37 AM 0.380425154 0.162002488 0.208550466 0.776866494 0.79340504 7:29:38 AM 0.727940393 0.622546124 0.716007768 0.660480612 0.02463804 7:29:39 AM 0.582772435 0.713406643 0.306544291 0.225257421 0.043552277 7:29:40 AM 0.371156954 0.163821476 0.780515577 0.032460418 0.356949005 7:29:42 AM 0.484167263 0.377878242 0.044189636 0.718147456 0.603177625 7:29:43 AM 0.294017186 0.463360581 0.962296024 0.504029061 0.183131098 7:29:44 AM 0.95635086 0.367849494 0.362230918 0.984421096 0.41587606 7:29:45 AM 0.198645523 0.754955312 0.280338922 0.79706146 0.730373691 7:29:46 AM 0.058483961 0.46774544 0.86783339 0.147418954 0.941713252 7:29:47 AM 0.411193343 0.340857813 0.162066261 0.943124515 0.722124394 7:29:48 AM 0.389312994 0.129281042 0.732723258 0.803458815 0.045824426 7:29:49 AM 0.549633038 0.73956852 0.542532728 0.618321989 0.358525184 7:29:50 AM 0.269925317 0.501399748 0.938234302 0.997577871 0.318813506 7:29:51 AM 0.798825842 0.24038537 0.958224157 0.660124357 0.07469288 7:29:52 AM 0.963581196 0.390150081 0.077448543 0.294604314 0.903519943 7:29:53 AM 0.890540963 0.50284339 0.229976565 0.664538451 0.926438543 7:29:54 AM 0.46951573 0.192568637 0.506730373 0.060557482 0.922857391 7:29:55 AM 0.56552394 0.952136998 0.739438663 0.107518765 0.911045415 7:29:56 AM 0.433149875 0.957190309 0.475811126 0.855705733 0.942255155 and this is the code I am using: [Data,Text] = xlsread('C:\Users\data.xlsx',2); IndexStart=strmatch('7:29:29 AM',Text,'exact'); %start time IndexEnd=strmatch('2:30:29 PM',Text,'exact'); %end time seconds = IndexEnd-IndexStart; TestData = Data([IndexStart: IndexEnd],:);
You probably need to: Use strfind to find the relevant string in the data imported Use datenum to convert the date to serial date numbers, to be able to calculate the elapsed time between the two points. It would help if you posted your code so far though. EDIT based on comments: Here's what I would do for cycling through the list of start and end times: [Data,Text] = xlsread('C:\Users\data.xlsx',2); start_times = {'7:29:29 AM','7:29:35 AM','7:29:44 AM','7:29:49 AM'}; % etc... end_times = {'2:30:29 PM','2:30:59 PM','2:31:22 PM','2:32:49 PM'}; % etc... elapsed_time = zeros(length(start_times),1); TestData = cell(length(start_times),1); % need a cell array because data can/will be of unequal lengths for k=1:length(start_times) IndexStart=strmatch(start_times{k},Text,'exact'); %start time IndexEnd=strmatch(end_times{k},Text,'exact'); %end time elapsed_time(k) = IndexEnd-IndexStart; TestData{k} = Data([IndexStart: IndexEnd],:); end
Use the "Import Data" from the Variable Tag in the Home menu. There you can set how you want the data to be imported like. With or without heading and the format.
R simplify heatmap to pdf
I want to plot a simplified heatmap that is not so difficult to edit with the scalar vector graphics program I am using (inkscape). The original heatmap as produced below contains lots of rectangles, and I wonder if they could be merged together in the different sectors to simplify the output pdf file: nentries=100000 ci=rainbow(nentries) set.seed=1 mean=10 ## Generate some data (4 factors) i = data.frame( a=round(abs(rnorm(nentries,mean-2))), b=round(abs(rnorm(nentries,mean-1))), c=round(abs(rnorm(nentries,mean+1))), d=round(abs(rnorm(nentries,mean+2))) ) minvalue = 10 # Discretise values to 1 or 0 m0 = matrix(as.numeric(i>minvalue),nrow=nrow(i)) # Remove rows with all zeros m = m0[rowSums(m0)>0,] # Reorder with 1,1,1,1 on top ms =m[order(as.vector(m %*% matrix(2^((ncol(m)-1):0),ncol=1)), decreasing=TRUE),] rowci = rainbow(nrow(ms)) colci = rainbow(ncol(ms)) colnames(ms)=LETTERS[1:4] limits=c(which(!duplicated(ms)),nrow(ms)) l=length(limits) toname=round((limits[-l]+ limits[-1])/2) freq=(limits[-1]-limits[-l])/nrow(ms) rn=rep("", nrow(ms)) for(i in toname) rn[i]=paste(colnames(ms)[which(ms[i,]==1)],collapse="") rn[toname]=paste(rn[toname], ": ", sprintf( "%.5f", freq ), "%") heatmap(ms, Rowv=NA, labRow=rn, keep.dendro = FALSE, col=c("black","red"), RowSideColors=rowci, ColSideColors=colci, ) dev.copy2pdf(file="/tmp/file.pdf")
Why don't you try RSvgDevice? Using it you could save your image as svg file, which is much convenient to Inkscape than pdf
I use the Cairo package for producing svg. It's incredibly easy. Here is a much simpler plot than the one you have in your example: require(Cairo) CairoSVG(file = "tmp.svg", width = 6, height = 6) plot(1:10) dev.off() Upon opening in Inkscape, you can ungroup the elements and edit as you like. Example (point moved, swirl added):
I don't think we (the internet) are being clear enough on this one. Let me just start off with a successful export example png("heatmap.png") #Ruby dev's think of this as kind of like opening a `File.open("asdfsd") do |f|` block heatmap(sample_matrix, Rowv=NA, Colv=NA, col=terrain.colors(256), scale="column", margins=c(5,10)) dev.off() The dev.off() bit, in my mind, reminds me of an end call to a ruby block or method, in that, the last line of the "nested" or enclosed (between png() and dev.off()) code's output is what gets dumped into the png file. For example, if you ran this code: png("heatmap4.png") heatmap(sample_matrix, Rowv=NA, Colv=NA, col=terrain.colors(32), scale="column", margins=c(5,15)) heatmap(sample_matrix, Rowv=NA, Colv=NA, col=greenred(32), scale="column", margins=c(5,15)) dev.off() it would output the 2nd (greenred color scheme, I just tested it) heatmap to the heatmap4.png file, just like how a ruby method returns its last line by default