I've got a file which has this structure:
Header 1
Header 2
config X Y
0.0 -5 -2
0.0 0 1
0.0 5 4
Header2
Config X Y
1.0 -5 -1
1.0 0 0
1.0 5 5
Header2
Config X Y
2.0 -5 0
2.0 0 1
2.0 5 6
Using gnuplot, I would like to plot columns 2:3 (Y as a function of X) with a few conditions:
Get rid of the headers and any line that's not filled with numbers
On the same graph, plot a new function (with a new label and a new color) each time the config changes. In the aforementioned case, you'd end up with three plots (one for config=0.0, one for config=1.0 and one for config=2.0)
Is there a one-liner for this in Gnuplot?
I tried to use the "every" keyword
p 'filename.txt' every ::3 u 2:3 w p
but to no avail
Thank you
If you have a strict data structure and you insist on a one-liner you could do the following with every, check help every.
However, then you need to know in advance that N=5 (here: 2 header lines and 3 data lines) and you have 3 blocks. You also skip the first 3 lines (check help skip).
You could use stats find out N automatically.
Personally, I would prefer a solution with more than one line, which would robust against little changes in data, just in case.
Script:
### separate data into subblocks with different colors
reset session
$Data <<EOD
Header 1
Header 2
config X Y
0.0 -5 -2
0.0 0 1
0.0 5 4
Header2
Config X Y
1.0 -5 -1
1.0 0 0
1.0 5 5
Header2
Config X Y
2.0 -5 0
2.0 0 1
2.0 5 6
EOD
plot for [i=0:2] N=5 $Data u 2:3 every ::i*N::(i+1)*N-1 skip 3 w lp pt 7 lc i ti sprintf("Config%d",i)
### end of script
Result:
Addition:
Here is a more general (but maybe not too obvious) solution:
you don't need to know in advance how many blocks you have and how many datalines you have
you can have different number of data lines
What the script does:
during plotting, the script checks if the column 1 contains a valid number, valid(1) will return 1 if it is a valid number and 0 otherwise (check help valid).
the variable c1 is initialized to 0. During plotting line by line c0 is assigned the value of c1 and c1 gets the value of valid(1).
so, everytime column 1 changes from text to numbers (i.e. c1>c0) increment b by 1 and use it for setting the color (check help lc variable)
plot keyentries in a loop with the corresponding title.
So, it is a two-liner which also could be put into a single line.
Script:
### separate data into subblocks with different colors (more flexibility)
reset session
$Data <<EOD
Header 1
Header 2
Header 3
config X Y
0.0 -5 -2
0.0 0 1
0.0 5 4 # could be followed e.g. by an empty line
Header2
Config X Y
1.0 -5 -1
1.0 0 0
1.0 5 5
1.0 6 6 # 4 data entries
Header2
Config X Y
Some other text line added
2.0 -5 0
2.0 0 1
2.0 5 6
2.0 6 7
2.0 7 6.5 # 5 data entries
EOD
set key top left noautotitle
plot c1=b=0 $Data u (c0=c1,c1=valid(1),$2):($3):(c1>c0?b=b+1:b-1) w lp pt 7 lc var, \
for [i=0:b-1] keyentry w lp pt 7 lc i ti sprintf("Config%d",i)
### end of script
Result:
I was plotting a bipartite graph using igraph package with R. There are about 10,000 edges, I want to expand the width of the whole plot to avoid state vertices overlapped.
my data looks like this:
> test2
user_id state meanlat meanlon countUS countS degState
<chr> <chr> <dbl> <dbl> <int> <int> <int>
1 -_1ctLaz3jhPYc12hKXsEQ NC 35.19401 -80.83235 909 3 18487
2 -_1ctLaz3jhPYc12hKXsEQ NV 36.11559 -115.18042 29 3 37884
3 -_1ctLaz3jhPYc12hKXsEQ SC 35.05108 -80.96166 4 3 665
4 -0wUMy3vgInUD4S6KJInnw IL 40.11227 -88.22955 2 3 1478
5 -0wUMy3vgInUD4S6KJInnw NV 36.11559 -115.18042 23 3 37884
6 -0wUMy3vgInUD4S6KJInnw WI 43.08051 -89.39835 20 3 3963
and below is my code on graph creating and setting.
g2 <- graph_from_data_frame(test2,directed = F)
V(g2)$type <- ifelse(names(V(g2)) %in% UserStateR$user_id, 'user', 'state')
V(g2)$label <- ifelse(V(g2)$type == 'user', " ", paste(names(V(g2)),"\n",as.character(test2$degState),sep=""))
V(g2)$size <- ifelse(V(g2)$type == 'user', 3, 20)
V(g2)$color <- ifelse(V(g2)$type == 'user', 'wheat', 'salmon')
V(g2)$type <- ifelse(names(V(g2)) %in% UserStateR$user_id, T, F )
E(g2)$color <- heat.colors(8)[test2$countS]
plot(g2,layout=layout.bipartite(g2, types = names(V(g2)) %in% UserStateR$state, hgap = 50, vgap = 50))
as you can see, I have tried to change the hgap and vgap arguments, but it doesn't work apparently. I have also tried asp argument, but that is not what I want.
I know this might be too late for #floatsd but I was struggling with this today and had a really hard time finding an answer, so this might help others out.
First, in general, there is a an attribute to iplot.graph called asp that very simply controls how rectangular your plot is. Simply do
l=layout.bipartite(CCM_net)
plot(CCM_net, layout=l, asp=0.65)
for a wide plot. asp smaller than 1 gives you a wide plot, asp larger than 1 a tall plot.
However, this might still not give you the layout you want. The bipartite command basically generates a matrix with coordinates for your vertices, and I actually don't understand yet how it comes up with the x-coordinates, so I ended up changing them myself.
Below the example (I am assuming you know how to turn your data into data frames with the edge list and edge/vertex attributes for making graphs so am skipping that).
My data is CCM_data_sign and is
from to value
2 EVI MAXT 0.67
4 EVI MINT 0.81
5 EVI P 0.70
7 EVI SM 0.79
8 EVI AMO 0.86
11 MAXT EVI 0.81
18 MAXT AMO 0.84
21 MEANT EVI 0.88
28 MEANT AMO 0.83
29 MEANT PDO 0.71
31 MINT EVI 0.96
39 MINT PDO 0.78
40 MINT MEI 0.66
41 P EVI 0.91
49 P PDO 0.77
50 P MEI 0.71
51 PET EVI 0.90
58 PET AMO 0.89
59 PET PDO 0.70
61 SM EVI 0.94
68 SM AMO 0.90
69 SM PDO 0.81
70 SM MEI 0.73
74 AMO MINT 0.93
76 AMO PET 0.66
79 AMO PDO 0.71
80 AMO MEI 0.83
90 PDO MEI 0.82
The data frame I generated for graphing is called CCM_net.
First a bipartite plot without any layout adjustments
V(CCM_net)$size<-30
l=layout.bipartite(CCM_net)
plot(CCM_net,
layout=l,
edge.arrow.size=1,
edge.arrow.width=2,
vertex.label.family="Helvetica",
vertex.label.color="black",
vertex.label.cex=2,
vertex.label.dist=c(3,3,3,3,3,3,3,3,3,3,3),
vertex.label.degree=c(pi/2,-pi/2,-pi/2,-pi/2,-pi/2,-pi/2,-pi/2,-pi/2,pi/2,pi/2,pi/2), #0 is right, “pi” is left, “pi/2” is below, and “-pi/2” is above
edge.lty=1)
This gives you the following
If I use asp I get the following
plot(CCM_net,
layout=l,
edge.arrow.size=1,
vertex.label.family="Helvetica",
vertex.label.color="black",
vertex.label.cex=2,
vertex.label.dist=c(3,3,3,3,3,3,3,3,3,3,3),
vertex.label.degree=c(pi/2,-pi/2,-pi/2,-pi/2,-pi/2,-pi/2,-pi/2,-pi/2,pi/2,pi/2,pi/2), #0 is right, “pi” is left, “pi/2” is below, and “-pi/2” is above
edge.arrow.width=2,
edge.lty=1,
asp=0.6) # controls how rectangular the plot is. <1 = wide, >1 = tall
dev.off()
This is looking better, but still not really what I want - see how some vertices are closer to each other than others?
So eventually I took the following approach. Setting the coordinates as bipartite looks like this
coords <- layout_as_bipartite(CCM_net)
coords
[,1] [,2]
[1,] 3.0 0
[2,] 0.0 1
[3,] 2.0 1
[4,] 3.5 1
[5,] 6.0 1
[6,] 1.0 1
[7,] 5.0 1
[8,] 7.0 1
[9,] 1.0 0
[10,] 4.5 0
[11,] 5.5 0
This matrix shows the x coordinates of your vertices in the first columns and the y coordinates in the second column, ordered according to your list with names. My list with names is
id name
1 EVI EVI
2 MAXT MAXT
3 MEANT MEANT
4 MINT MINT
5 P P
6 PET PET
7 SM SM
8 SR SR
9 AMO AMO
10 PDO PDO
11 MEI MEI
In my graph, EVI, AMO and PDO are on the bottom, but note their x coordinates: 3.0, 1.0, 4.5 and 5.5. I haven't figured out yet how the code comes up with that, but I don't like it so I simply changed it.
coords[,1]=c(2,0,4,8,12,16,20,24,9,16,24)
Now the plotting code (also with asp) and the output becomes
plot(CCM_net,
layout=coords,
edge.arrow.size=1,
vertex.label.family="Helvetica",
vertex.label.color="black",
vertex.label.cex=1,
vertex.label.dist=c(4,4,4,4,4,4,4,4,4,4,4),
vertex.label.degree=c(pi/2,-pi/2,-pi/2,-pi/2,-pi/2,-pi/2,-pi/2,-pi/2,pi/2,pi/2,pi/2), #0 is right, “pi” is left, “pi/2” is below, and “-pi/2” is above
edge.arrow.width=2,
edge.lty=1,
asp=0.6) # controls how rectangular the plot is. <1 = wide, >1 = tall
Now the vertices are nicely spaced in a rectangular plot!
Note - I also decreased the size of the vertices, the size of the labels and their positioning, for better readability.
I think you can output with PDF. then zoom in.
Or, use rgexf package to output gexf file. Then visualizate in gephi.
I think gephi is a good tools for network visualization.
Hey guys I'm trying to do a real heat map like in A true heat map in R, but in GNUPLOT.
My file is like
3 1 2
3 4 3
3 5 5
4 1 7
4 1 2
4 4 3
4 5 2
5 1 3
5 1 2
5 4 3
.
..
....
and I've tried with
plot "file" using 1:2:3 with image
splot "file" using 1:2:3 p3md
etc..
Also I follow this example http://gnuplot.sourceforge.net/demo/heatmaps.html, but nothing.
Can someone shed some light here please?
Thanks
set pm3d interpolate 2,2
splot "file"
You can adjust level of interpolation by changing the number or even set it as 0 to tell gnuplot to "guess" it. It is not well documented what interpolation method that gnuplot is using, so be careful.
set pm3d interpolate 0,0
splot "file"
Here's the result without interpolation:
Here's the result with interpolation 2,2:
Here's the result with interpolation 0,0:
Use the pm3d option:
set pm3d
splot "file"
I am trying to plot two graphs using different columns from the same data file. As the range of one graph is far greater than the other, I am setting the y-axis to a logarithmic scale. As the domain of values are also very small for both graphs, I am also setting the x-axis to a logarithmic scale.
I have no problem plotting the graphs except that gnuplot does not plot the first points in the data file (where x = 0).
The code that I am using to plot the graphs is thus:
set xrange [1:2500]
set yrange [1:2000]
set log x
set log y
plot "datafile.txt" using 1:2 with lines, "datafile.txt" using 1:3 with lines
Note that, because I am using a logarithmic scale for both axes, I cannot include the value of zero in either range.
An excerpt of the data file that I am using is thus:
Table of Results: Range: {-50...50}
Dim #AvgP #AvgNP
0 0 1743
1 0 564
2 0 914
3 0 1040
4 0 1072
5 0 1005
6 0 815
7 1 689
8 3 525
9 4 433
10 3 350
11 0 255
12 1 216
13 2 140
14 2 84
15 1 57
16 0 38
17 0 16
18 0 15
19 1 7
20 0 2
21 0 1
22 0 1
23 0 0
24 0 0
25 0 0
. . .
. . .
. . .
The file that is plotted is thus:
Notice how the first value of the second graph is not plotted.
As you note, the x=0 point isn't defined on a logarithmic axis, so it being omitted is what you should expect to happen. If you want to force that point to be included, shift the x values by adding 1 to each value, and give an appropriate axis label to make clear what it being plotted.
plot "datafile.txt" using ($1+1):2 with lines, "datafile.txt" using ($1+1):3 with lines
With this, you should see the missing point on the green line. The red line will be unchanged, as the value y=0 can't be plotted either. You could shift the y values as well, if desired.
Here's how it looks: