buchi2 has asked for the wisdom of the Perl Monks concerning the following question:

Hello!

I have to plot several diagramms and want to do it with chart::gnuplot.

It needs the x and y as arrayref with
xdata => \@xarray, ydata => \@yarray,
I want to plot the diagramms with a loop.
Where the data is coming from is different for the loop elements, so that I have to put it before into a structure, over it then I can loop.
Not every index is filled. First I try to differ between and choose therefore i and ii, but then I dicide to use only the index i and skip the unfilled indexe during plotting.
This is the part of my code:
# die Plotfelder/-hashe belegen und hash istart $ii = -1; for ($i = 0; $i <= $#yfeld; $i++) { # next if ($yfeld[$i] == 0); $ii = $ii + 1; print "$i $ii "; push(@ploty,$yfeld[$i]); push @{$istart{$ii}}, $istart[$i]; push @{$ianz{$ii}}, $ianz[$i]; if ($xfeld[$i] eq 'x') { push @{$plotx{$ii}}, @xfix; print "x\n"; } elsif ($xfeld[$i] eq 'y') { push @{$plotx{$ii}}, @yfix; print "y\n"; } else { push @{$plotx{$ii}}, $fnfeld[$xfeld[$i]]->{'fn'}; print "$xfeld[$i]\n"; } } print "\n"; print "2 $plotx{2}[3]\n"; print "3 $plotx{3}[3]\n"; print "5 $plotx{5}[3]\n"; # ? print "6 $plotx{6}[3]\n"; print "7 $plotx{7}[3]\n"; # ? print "8 $plotx{8}[3]\n"; # ? print "9 $plotx{9}[3]\n";
The prints in the loop are for checking. It seems all correct.
0 0 0 1 1 0 2 2 y 3 3 y 4 4 0 5 5 5 6 6 x 7 7 5 8 8 5 9 9 y
I ommit the index 0, 1, 4, because it is empty (0 in the first print-block).
But the print-check at the end of my code snippet gives this:
2 3.640000E-04 3 3.640000E-04 Use of uninitialized value in concatenation (.) or string at test.pl l +ine 590. 5 6 3.640250E-04 Use of uninitialized value in concatenation (.) or string at test.pl l +ine 592. 7 Use of uninitialized value in concatenation (.) or string at test.pl l +ine 593. 8 9 3.640000E-04
So it means, that something goes wrong, where I want to assign the fnfeld to my plotx.
I read this "References quick reference" and my brain has meanwhile several knots to thinking about this. But I have no idea, what is wrong with the syntax.
I think, it is the reference, because I use it successfull for plotting:
ydata => $fnfeld[$ploty[$ii]]->{'fn'},
But how can I assing the values from the array of hashes, which contains an array?

Regards, buchi

Replies are listed 'Best First'.
Re: question to a complex structure of hash/array
by thanos1983 (Parson) on Aug 08, 2017 at 12:01 UTC

    Hello buchi2,

    Can you provide us a working / compiling piece of code. I would like to test your code but I am not able because I am missing parts.

    Regarding the for loop that you have...you can write it in a Perl way also:

    for ($i = 0; $i <= $#yfeld; $i++)

    Assuming that $#yfeld is an array @yfeld.

    for my $i (0 .. $#yfeld)

    I also do not understand why you instantiate $ii = -1; and on the next step 3 lines after you are adding 1 $ii = $ii + 1; which will result to 0. You can get this value from your for loop why you need to apply this calculation? Unless I am missing something here, that is hidden in the rest of the code that is missing.

    Looking forward to your update, BR

    Seeking for Perl wisdom...on the process of learning...not there...yet!
      Hello!

      >I also do not understand why you instantiate $ii = -1; and on the next step 3 lines after you are adding 1 $ii = $ii + 1; which will result to 0. You can get this value from your for loop why you need to apply this calculation?

      I removed this now with $ii and $i and use only $i.
      I had e.g. (0 1 2 3 0 0 0 7 0 9) as an input and my first try was, to keep these structure and take another structure, which only contain the places, which are not 0.

      Regards, buchi

Re: question to a complex structure of hash/array
by BillKSmith (Monsignor) on Aug 08, 2017 at 15:48 UTC

    When $xfeld$I is equal to either an 'x' or a 'y', You push an array into the output. Otherwise you push a scalar. Your final prints expect the array. Your first print section shows that you stored the scalar when $i was equal to 0,1,4,5,7, and 8. Your final section would fail for all of these, but you do not try to print for $i equal to 0, 1, or 4. It does fail when $i is equal to 5, 7, and 8. Your print works as expected for the other cases (2, 3, 6, and 9).

    I cannot suggest a solution, because you have not shown us any data.

    UPDATE: Added code which duplicates the posted output. Removed irrelevant code from and added initialization to originally posted code. A dump of the output hash %plotx reveals what happens.

    use strict; use warnings; use Data::Dumper; # Data infered from posted output. my @xfeld = qw(0 0 y y 0 5 x 5 5 y); my @xfix = qw( UNKNOWN_x_0 UNKNOWN_x_1 UNKNOWN_x_2 3.640250E-4 ); my @yfix = qw( UNKNOWN_y_0 UNKNOWN_y_1 UNKNOWN_y_2 3.640000E-4 ); my @fnfeld = ( {fn => 'UNKNOWN_n_0',}, {fn => 'UNKNOWN_n_1',}, {fn => 'UNKNOWN_n_2',}, {fn => 'UNKNOWN_n_3',}, {fn => 'UNKNOWN_n_4',}, {fn => 'UNKNOWN_n_5',}, {fn => 'UNKNOWN_n_6',}, {fn => 'UNKNOWN_n_7',}, {fn => 'UNKNOWN_n_8',}, {fn => 'UNKNOWN_n_9',}, ); my @yfeld; $#yfeld = $#xfeld; my %plotx; my $ii = -1; for (my $i = 0; $i <= $#yfeld; $i++) { $ii = $ii + 1; print "$i $ii "; if ($xfeld[$i] eq 'x') { push @{$plotx{$ii}}, @xfix; print "x\n"; } elsif ($xfeld[$i] eq 'y') { push @{$plotx{$ii}}, @yfix; print "y\n"; } else { push @{$plotx{$ii}}, $fnfeld[$xfeld[$i]]->{'fn'}; # The Previous statement stores only one value. # The failing prints expects at least four. print "$xfeld[$i]\n"; } } print "\n"; print "2 $plotx{2}[3]\n"; print "3 $plotx{3}[3]\n"; print "5 $plotx{5}[3]\n"; # Array element does not exist print "6 $plotx{6}[3]\n"; print "7 $plotx{7}[3]\n"; # Array element does not exist print "8 $plotx{8}[3]\n"; # Array element does not exist print "9 $plotx{9}[3]\n"; print Dumper(\%plotx); OUTPUT: 0 0 0 1 1 0 2 2 y 3 3 y 4 4 0 5 5 5 6 6 x 7 7 5 8 8 5 9 9 y 2 3.640000E-4 3 3.640000E-4 Use of uninitialized value in concatenation (.) or string at buchi2.pl + line 41. 5 6 3.640250E-4 Use of uninitialized value in concatenation (.) or string at buchi2.pl + line 43. 7 Use of uninitialized value in concatenation (.) or string at buchi2.pl + line 44. 8 9 3.640000E-4 $VAR1 = { '1' => [ 'UNKNOWN_n_0' ], '8' => [ 'UNKNOWN_n_5' ], '6' => [ 'UNKNOWN_x_0', 'UNKNOWN_x_1', 'UNKNOWN_x_2', '3.640250E-4' ], '3' => [ 'UNKNOWN_y_0', 'UNKNOWN_y_1', 'UNKNOWN_y_2', '3.640000E-4' ], '2' => [ 'UNKNOWN_y_0', 'UNKNOWN_y_1', 'UNKNOWN_y_2', '3.640000E-4' ], '9' => [ 'UNKNOWN_y_0', 'UNKNOWN_y_1', 'UNKNOWN_y_2', '3.640000E-4' ], '7' => [ 'UNKNOWN_n_5' ], '5' => [ 'UNKNOWN_n_5' ], '0' => [ 'UNKNOWN_n_0' ], '4' => [ 'UNKNOWN_n_0' ] };
    Bill
      > push an array

      push @results, @array; extends @results by the elements of @array, it doesn't "push an array", as all the elements of an array must be scalars. You can push an array reference, though:

      push @results, \@array;

      ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
        Hello!

        Thanx to all. I will try to give a running code.

        With the dumper there is the problem, that are some hundret values.
        ydata => $fnfeld[$ploty[$ii]]->{'fn'},
        This call to gnuplot is working.
        But this not:
        push @{$plotx{$ii}}, $fnfeld[$xfeld[$i]]->{'fn'}; . . . xdata => $plotx{$ii},
        It is empty.
        I will try to create a short standalone code.

        Regards buchi

        Hello!

        >push @results, @array; extends @results by the elements of @array, it doesn't "push an array", as all the elements of an array must be scalars. You can push an array reference, though:

        yes, thanks, so to getting it keep as an array, I push it to a hash.

        e.g.
        my %plotx; my $i; my @xfix; push @{$plotx{$i}}, @xfix;
        Regards, buchi
Re: question to a complex structure of hash/array
by Anonymous Monk on Aug 08, 2017 at 14:17 UTC
    Perl debugging 101:
    use Data::Dumper; print Dumper(\@plotx);
Re: question to a complex structure of hash/array
by Anonymous Monk on Aug 08, 2017 at 14:38 UTC

    Just taking a stab in the dark, I'm thinking that this:

    push @{$plotx{$ii}}, $fnfeld[$xfeld[$i]]->{'fn'};

    possibly should be this instead:

    push @{$plotx{$ii}}, @{$fnfeld[$xfeld[$i]]->{'fn'}};

    But the whole thing seems needlessly complicated. Agree with thanos that it would help if we could see more of your program, particularly the call to Gnuplot.

      Hello!
      push @{$plotx{$ii}}, @{$fnfeld[$xfeld[$i]]->{'fn'}};
      results:
      Can't use an undefined value as an ARRAY reference at testl.pl line 585

      Regards buchi

        Hello!

        I dont know, what was going wrong before, but the line

        push @{$plotx{$ii}}, @{$fnfeld[$xfeld[$i]]->{'fn'}};
        is working now. :)
        Thanx.

        Regards, buchi