gnuplot histogram with Perl: How to put values on top of bars - perl

How can the following gnuplot plot can be generate using Perl ?
(I need a histogram where under each bar I will write the difference between that column and the column on its right side, with the same data)
The problem is that I didn't figure out how to put numbers under the bars, using Perl.
This is the code of gnuplot:
reset
set terminal png
set output 'StackOverflow.png'
set style fill solid 1.00
set style histogram clustered gap 1
set style data histograms
set yrange [0:120]
set xtics norangelimit font ",8"
set ytics norangelimit font ",8"
set key font ",8"
set key width -8
xoffset=0.17
yoffset=0.03
plot 'data.dat' using 2:xtic(1) with histogram title "Parameter 1", \
'' u 3 with histogram title "Parameter 2", \
'' u 0:2:4 with labels offset -0.9,0.5 title "", \
'' u 0:3:5 with labels offset 2.0,0.5 title ""
Currently I have generated the following using Perl:
And this is the Perl code:
#!/usr/bin/perl -w
use strict;
use Chart::Gnuplot;
my $chart = Chart::Gnuplot->new(
output => 'plotStyle_19.png',
yrange => [0, 120],
bg => {
color => "#c9c9ff",
density => 0.2,
},
);
my #x = qw( A B C D );
my $h1 = Chart::Gnuplot::DataSet->new(
xdata => \#x,
ydata => [99, 97, 97, 95],
title => "1st data set",
color => "purple",
fill => {density => 0.2},
style => "histograms",
);
my $h2 = Chart::Gnuplot::DataSet->new(
xdata => \#x,
ydata => [9, 10, 13, 15],
title => "2nd data set",
color => "dark-green",
fill => {density => 0.2},
style => "histograms",
);
$chart->plot2d($h1, $h2);

Related

Changing axis label color in LightningChart JS

The chart appears with dark background, axis numeric labels in grid positions are yellow.
How do I change axis label colors to white?
E.g. in this example https://www.arction.com/lightningchart-js-interactive-examples/#edit/lcjs_example_0001_simpleScatter
I'm trying
chart.getDefaultAxisX()
.setInterval(0, 92 * dataFrequency)
.setTickStyle((visibleTicks) => visibleTicks
.setLabelFillStyle( color: ColorRGBA(255, 255, 255) })
)
But it's giving SyntaxError: Unexpected token, expected ","
According to the documentation it expects you to pass FillStyle, not just color. The solution for your case is as follows:
chart.getDefaultAxisX()
.setInterval(0, 92 * dataFrequency)
.setTickStyle( (visibleTicks) => visibleTicks
.setLabelFillStyle(
new SolidFill( { color: ColorRGBA(255, 255, 255) } )
)
)

How to get string value centered above bars in bar chart

I am having trouble aligning the text above the correct bars in the following bar graph, I can't figure out where it's going wrong?
CODE:
bar(two_weeks,zAxis);
text(1:length(two_weeks),zAxis,num2str(zAxis),'vert','bottom','horiz','center');
box off
ylabel('Z Axis')
BAR CHART:
The arrows were added post production and are showing where they should be aligned to. Also note that I was too lazy to draw all of the arrows.
DATA:
two_weeks =
1×14 datetime array
[ 21-Nov-2018, 22-Nov-2018, 23-Nov-2018, 24-Nov-2018, 25-Nov-2018, 26-Nov-2018, 27-Nov-2018, ...
28-Nov-2018, 29-Nov-2018, 30-Nov-2018, 01-Dec-2018, 02-Dec-2018, 03-Dec-2018, 04-Dec-2018 ]
zAxis =
[ 5, 12, 1, 7, 13, 24, 2, 27, 62, 0, 3, 17, 74, 4 ].'
Your x axis is specified using a datetime array. What you're then using is guesswork to align indices (1:length(two_weeks)) for the x coordinates of your text items.
Instead, simply use the same datetime array for the position of the text!
bar( two_weeks, zAxis );
text( two_weeks, zAxis, arrayfun(#num2str,zAxis,'uni',0) );
As you did in the question, we want to set 'VerticalAlignment' to 'bottom' and 'HorizontalAlignment' to 'center' to neaten things up above the bars:
bar( two_weeks, zAxis );
text( two_weeks, zAxis, arrayfun(#num2str,zAxis,'uni',0), ...
'VerticalAlignment', 'bottom', 'HorizontalAlignment', 'center' );
Output:

Alignment of text in matlab 'text' command

I want to print the following text on a matlab figure with ':' sign vertically aligned:
Total Events: 1234
Mean Value: 1234
Standard Deviation: 1234
1st Quartile: 1234
...
...
I am using text function and trying to insert spaces manually but they never seemed to be aligned perfectly and looks wavy.
Any helps, please.
You can use a fixed-width font and use a cell array to put the text on different lines:
text( 0, 0, { ' Total Events: 1234' ...
' Mean Value: 1234' ...
'Standard Deviation: 1234' ...
' 1st Quartile: 1234' }, 'FontName', 'FixedWidth' )
Use string format
strings = {'Total Events', 'Mean Value', 'Standard Deviation', '1st Quartile'};
max_len = max( cellfun( #numel, strings ) );
fs = sprintf( '%% %ds: 1234\n', max_len );
cellfun( #(x) fprintf(1,fs,x), strings );
Results with:
Total Events: 1234
Mean Value: 1234
Standard Deviation: 1234
1st Quartile: 1234
As you can see the command that aligns to the right is
sprintf( '% 18s: 1234', strings{1} )
So, eventually in your text command, instead of explicitly writing a string, you can format one using sprintf:
text( 0, 0, sprintf( '% 18s: %d', strings{ii}, values(ii) );
Assuming you have strings - cell array of strings and same-length array values with corresponding values to print.

How do I keep GD::Graph from writing the last X label and overwriting my other labels?

I set x_label_skip to skip labels, but it still tries to display the very last label and it is overwriting the other label, and looks messy. It shouldn't be writing the last label. It should be skipping the last label. I set the number of labels to skip as a function of how many data points there are.
This is what it looks like:
Code:
my $graph = GD::Graph::lines->new(400, 500);
$graph->set(
r_margin => 2,
x_label => 'Date',
y_label => 'Price',
title => "$symbol1, $symbol2",
dclrs => [ qw(lred lblue lgreen lyellow lpurple cyan lorange) ],
transparent => 0,
x_labels_vertical => 1,
x_label_skip => int ((#tmpDate * 8)/(400-50) + 1), # a function of # of data points, each label 8px. More labels, more skip.
) or die $graph->error;
Ok I found it. Just use modulo to divide the # of entries by # of labels to skip, and use that as the offset. It seems GD::Graph will always want to print the last label, so can't control that, but you can control the 1st label to print. Seems backwards to me but whatever.
my $graph = GD::Graph::lines->new(400, 500);
my $skip = int ((#tmpDate * 8)/(400-50) + 1); # a function of # of data points, each label 8px. More labels, more skip.
$graph->set(
r_margin => 2,
x_label => 'Date',
y_label => 'Price',
title => "$symbol1, $symbol2",
dclrs => [ qw(lred lblue lgreen lyellow lpurple cyan lorange) ],
transparent => 0,
x_labels_vertical => 1,
x_label_skip => $skip,
x_tick_offset => #tmpDate % $skip, # ensure last label doesn't overwrite second-to-last label
) or die $graph->error;
x_last_label_skip => 1 works exactly as you need it, just skipping the last label. Probably it wasn't implemented in 2012, but now it is.

Perl & Image::Magick, getting color values by pixel

I'm using Perl and the Image::Magick module to process some JPEGs.
I'm using the GetPixels sub to get the RGB components of each pixel.
e.g.
my #pixels = $img->GetPixels(
width => 1,
height => 1,
x => 0,
y => 0,
map => 'RGB',
#normalize => 1
)
print Dumper \#pixels;
$img->Resize(
width => 1,
height => 1,
filter => 'Lanczos'
);
#pixels = $img->GetPixels(
width => 1,
height => 1,
x => 0,
y => 0,
map => 'RGB',
#normalize => 1
);
print Dumper \#pixels;
$img->Write('verify.jpg');
I've found that getPixels is returning two bytes per channel, e.g.
$VAR1 = [
46260,
45232,
44975
];
$VAR1 = [
58271,
58949,
60330
];
Before the call to Resize: (in this example) the colour of the designated pixel is #b4b0af, and the returned values are 0xB4B4, 0xB0B0, 0xAFAF. I don't understand why this is, but I can deal with it using MOD 256;
But after the call to Resize, the returned values don't correspond in any obvious way to the actual values I find in the output file (verify.jpg).
Is Image::Magick just being super-precise (accounting for the shorts instead of bytes)?
And does the JPEG compression account for the discrepancy between the second Dumper output and the contents of 'verify.jpg'?
Read all about colors in ImageMagick, including its quantum depth:
ImageMagick may be compiled to support 32 or 64 bit pixels of type PixelPacket. This is controlled by the value of the QuantumDepth define. The default is 64 bit pixels, which provides the best accuracy.
You might also like to read about how it does color reduction.
JPEG compression is lossy, so there's no direct correspondence between the pixel values before saving and the pixels in the compressed image. You'd have to load the new image if you want to find out how the compression modified it.
Took me some time to get the same problem solved for binary (black & white) tiffs:
for my $y (0..$height-1) {
my #pixels = $image->GetPixels(
'width' => 1,
'height' => 1,
'x' => 0,
'y' => $y,
map => 'RGB',
normalize => 'True',
);
print "$y: ",join(', ', #pixels),"\n";
}
Prints (shortened):
627: 1, 1, 1
628: 1, 1, 1
629: 0, 0, 0
630: 0, 0, 0
631: 0, 0, 0
632: 0, 0, 0
633: 1, 1, 1
634: 1, 1, 1
Found no better way.