multiple line-plots in gnuplot using C - c

For a terminal application written in C I need to plot (in the terminal) two tables as line plots. To do this I use (following e.g. gnu tutorial)
FILE *gnuplot = popen("gnuplot", "w");
...
fprintf(gnuplot, "plot '-' u 1:2 t 'data1' w lp lt 0\n");
for (int i = 0; i < lines; ++i) {
fprintf(gnuplot,"%f %f \n", x[i] - x[0], y[i]);
}
fprintf(gnuplot, "\n");
fprintf(gnuplot, "t 'data2' lt 2\n");
for (int i = 0; i < lines; ++i) {
fprintf(gnuplot,"%f %f \n", x[i] - x[0], 0.4*(x[i] - c0)/c1);
}
fprintf(gnuplot, "e\n");
fflush(gnuplot);
The problem is that the data is plotted as one data block instead of two different ones. I expected to have a separation by using the line
fprintf(gnuplot, "t 'data2' lt 2\n");
which seems not to be the case. What is wrong in this code?

You probably want to do the following. Each inline data has to be terminated by an e.
In gnuplot console it would be:
plot '-' u 1:2 t 'data1' w lp lt 0, '' u 1:2 t 'data2' lt 2
1 0.1
2 0.2
3 0.3
4 0.4
e
11 0.5
12 0.6
13 0.7
14 0.8
e
Check help inline data and help special-filenames.
Although, to my opinion it is a bit confusing and suitable examples are missing. Maybe you can find them elsewhere.

Related

Making a diamond with specific widht and height in c (gnuplot)

So I am trying to make a program that outputs the coordinates of a diamond of n width and n height and then represent the figure.out that is done with the program with gnuplot. I have this code done already but I want to make it easier.
#include <stdio.h>
#include <stdlib.h>
#define DEF 10
int main()
{
float def_an,def_al,slope,i,j,height,width;
FILE *out = fopen ( "diamond.out", "w" );
if(out==NULL)
{
printf("Wrong output");
return 1;
}
printf("Introduce the height: ");
scanf("%f", &height);
printf("Introduce the width: ");
scanf("%f", &width);
def_al=(height/DEF);
def_an=(width/DEF);
slope=(height/width);
for(j=0;j<= height/2;j+=def_al)
{
for(i=((j-(height/2))/slope);i<=(((height/2)-j)/slope);i+=def_an)
{
printf("%.2f %.2f\n",i,j);
fprintf (out, "%.2f %.2f\n", i,j );
}
}
for(j=(0-def_al);j>= -height/2;j-=def_al)
{
for(i=(((-height/2)-j)/slope);i<=((j-(-height/2))/slope);i+=def_an)
{
printf("%.2f %.2f\n",i,j);
fprintf (out, "%.2f %.2f\n", i,j );
}
}
fclose(out);
return 0;
}
Plotting a bunch of customized diamonds is not as straightforward as you might think.
Of course, you can use the suggestions Eldrad mentioned in the comments, but the plotting style with polygons is for splot and "3D"-plotting (which probably could also be used for 2D as well).
So, instead of plotting data you could draw objects (check help polygon) in a for loop from data in a datablock.
The example below is just gnuplot code. You have to create this text with C or any other language and send it to gnuplot.
Code:
### plotting diamonds in custom size
reset session
# x, y, width, height
$Diamonds <<EOD
0 0 3 5
5 0 2 1
4 4 3 2
-7 5 4 4
-6 -6 3 5
6 -6 7 2
EOD
x(n) = word($Diamonds[n],1)
y(n) = word($Diamonds[n],2)
w(n) = word($Diamonds[n],3)
h(n) = word($Diamonds[n],4)
set size square
set xrange [-10:10]
set yrange [-10:10]
do for [i=1:|$Diamonds|] {
set object i polygon from x(i),y(i)+h(i)/2. to x(i)+w(i)/2.,y(i) to x(i),y(i)-h(i)/2. to x(i)-w(i)/2.,y(i) to x(i),y(i)+h(i)/2.
set object i fc lt i fillstyle solid 1.0 border
}
plot NaN notitle # empty dummy plot or plot something else
### end of code
Result:

C program is ending by itself during nested loop

My C program is ending on it's own and I can't figure out the issue. I have added a comment above the loop where it is stopping.
I am creating a program to match dna samples in arrays with each other. The dna samples are floats and I am reading them from a file.
This is the file I am reading from:
2.3 3.3 4.5 6.7 7.8 2.1 3.2 4.3 5.2 6.5
5
2.3 3.3 4.5 6.7 7.8 2.1 3.2 4.3 5.2 6.5
1.3 0.3 9.5 8.7 5.8 4.1 3.2 2.3 6.2 6.9
6.3 9.3 4.3 6.4 7.5 2.9 3.0 4.1 5.3 6.5
6.1 9.4 4.5 6.6 7.4 2.8 3.2 4.4 5.0 6.0
2.3 3.3 4.5 6.6 7.8 2.2 3.2 4.3 5.2 6.5
The expected output is all the values will be printed (5 lines for the criminal samples) and the first line will be matched and the rest will not. However this is my output:
Reading chromosomes of the suspect.
2.3 3.3 4.5 6.7 7.8 2.1 3.2 4.3 5.2 6.5
Reading chromosomes of the criminals.
2.3 3.3 4.5 6.7 7.8 2.1 3.2 4.3 5.2 6.5
1.3 0.3 9.5 8.7 5.8 4.1 3.2 2.3 6.2
I have attempted debugging it and at one point it was randomly assigning my sizeR variable to like 10000 or something during the loop and I assumed that was the problem somewhere but now it's not I'm struggling to understand why it is still stopping for me.
Code:
#include <stdio.h>
#include <stdbool.h>
FILE *fp;
int main(){
fp = fopen("dna_input.txt", "r");
int sizeR = 0, sizeC = 10; // declare size variables
float suspect[sizeC]; // declaring suspect array
float criminal[sizeR][sizeC]; // declaring criminal array
// reads 10 input values from first line of the file
printf("Reading chromosomes of the suspect. \n");
for (int i = 0; i < sizeC; i++){
fscanf(fp, " %f", &suspect[i]);
printf("%.1f ", suspect[i]);
}
printf("\n");
// reads integer from 2nd line of file for the amount of lines to read for next loop
fscanf(fp, " %d", &sizeR);
printf("Reading chromosomes of the criminals. \n");
// read 10 input values into 5 criminal arrays
// THIS LOOP IS WHERE MY PROGRAM IS STOPPING <---------------------------------------------
for (int i = 0; i < sizeR; i++){
for (int j = 0; j < sizeC; j++){
fscanf(fp, " %f", &criminal[i][j]);
printf("%.1f ", criminal[i][j]);
}
printf("\n");
}
// check for match
bool match = true;
for (int i = 0; i < sizeR; i++){
for (int j = 0; j < sizeC; j++){
if (suspect[j] != criminal[i][j]){
match = false;
}
}
// display matching result
if (match)
printf("The two profiles match! \n");
else
printf("The two profiles don't match! \n");
}
fclose(fp);
return 0;
}
You need to dynamically allocate the criminals array.
//Here sizeR is 0 so you are declaring criminal[0][10]
float criminal[sizeR][sizeC]; // declaring criminal array
Typical buffer overflow problem.
Thank you for the comments, I missed that completely. I've moved my criminal array to be declared after the fscanf
// reads integer from file for the amount of lines to read
fscanf(fp, " %d", &sizeR);
// declare criminal aray
float criminal[sizeR][sizeC];

Trouble printing 5 elements of a double array per line in C

I've been working on an assignment for school, basically we're creating 2 arrays of random doubles, then sorting them using 3 different algorithms and printing the results. The output needs to be printed with 5 elements per line.
I've got this code:
//print sorted arrayB
for (i = 0; i < size; i++)
{
printf ("%.1lf ", arrayB[i]);
if (i % 5 == 0 && i > 0)
{
printf ("\n");
}
}
where all variables are defined before the sort, and my output looks like this every time:
1.0 2.0 3.0 4.0 5.0 6.0
7.0 8.0 9.0 10.0 11.0
12.0 13.0 14.0 15.0 16.0
17.0 18.0 19.0 20.0 21.0
etc...
I don't understand why it's printing 6 elements in the top row, and 5 in all the rest. Any help is greatly appreciated!
Just write the evaluation by hand for your conditional:
if (i % 5 == 0 && i > 0)
i result
0 false
1 false
2 false
3 false
4 false
5 true
6 false
Now we can see that it is false 5 times, then true, which makes it print a newline, but only after you printed the number!
So you need to rearrange your logic slightly, but the conditional is correct.
The point is in the && i > 0 part of the if statement. If you'd remove it, this would be the output:
1.0
2.0 3.0 4.0 5.0 6.0
7.0 8.0 9.0 10.0 11.0
12.0 13.0 14.0 15.0 16.0
17.0 18.0 19.0 20.0 21.0
etc...
By excluding zero, you have prevented printing the newline after the first number, see?
The solution is to move the i index by one, like this:
if ((i + 1) % 5 == 0)
{
printf ("\n");
}
Now you don't even need the && i > 0 part, because i + 1 will never be zero.
You need to update the \n condition as below -
if ((i+1) % 5 == 0)
{
printf ("\n");
}
i % 5 will cause newlines after indices 5,10,15... This is your case where you have 6 at index 5, 11 at index 10..
Rather you need to break at 4,9,14... which are all covered by (i+1).
Just add 1 to i(therefore the condition i > 0, becomes unnecessary), which will solve. This occurs because in the condition imposed by you, for the first line break (\ n) to occur, it will have to go from 0 to 5, and to do so you will have to repeat the loop 6 times, so on the first line it showed 6 numbers , instead of 5
Like this:
#include <stdio.h>
#define SIZE 25
int main() {
int i, arrayB[SIZE] = {0};
for (i = 0; i < SIZE; i++)
{
printf ("%.1lf ", arrayB[i]);
if ((i+1) % 5 == 0)
{
printf ("\n");
}
}
return 0;
}

output keep in the same column ignoring "-" (negative)

This is the output I expect
x |x|
1.2 1.2
-2.3 2.3
3.4 3.4
but I keep getting this:
x |x|
1.2 1.2
-2.3 2.3
3.4 3.4
Here is my part of code:
printf(" x |x|\n");
for (i = 1; i <= n; i++)
{
printf(" %.1f %.1f\n", array[i], array1[i]);
}
how do I change it?
You should specify a number before dot in %.1f that shows all the number including '-' for example:
printf("%3.1f",array[i]);
Will result in :
x |x|
1.2 1.2
-2.3 2.3
3.4 3.4
It means that a number should fill 3 places in screen.
Sorry for bad English.

Gnuplot and C "x range is invalid"

I'm trying to generate a data file and to plot it with Gnuplot. The problem is when I keep my Nstep lower than 348 I get the error
line 0: warning: Skipping data file with no valid points
plot 'plot.txt' using 1:2 with lines
^
line 0: x range is invalid
But I keep the Nstep higher than 348 everything works fine. I do not understand why. Here is my C code:
int main(void){
int Nstep = 348;
//omitted part...
FILE *pipe = fopen("plot.txt", "w+");
while (n<Nstep) {
pos[n+1] = pos[n] + v[n]*h;
v[n+1] = v[n] + h * Fx(pos[n]);
fprintf(pipe, "%d %05.3lf\n", n, v[n]);
n++;
}
close(pipe);
system("gnuplot -p -e \"plot 'plot.txt' using 1:2 with lines\"");
return 0;
}
plot.txt example (Nstep = 10)
1 100.000
2 99.000
3 97.000
4 94.010
5 90.050
6 85.150
7 79.349
8 72.697
9 65.252
10 57.079
I am unable to replicate your error as you didn't include the full source (function Fx and definitions of pos and v). You are calling the wrong close. You should call fclose() (this will flush the file handle too).
fclose(pipe)
And not
close(pipe)
You could explicitly flush the data by calling fflush().

Resources