How to get Gnuplot not to crop scientific notation - resize

I'm using gnuplot to generate the following surface plot.
The important part of the command file I'm using is:
set terminal pdfcairo size 3,3;
In particular the size 3,3 resizes the plot to the way I want but crops out part of the z-axis label in the process. If I use a wider size like size 4,3 or don't use the size option at all then the z-axis labels fit as follows:
It seems that gnuplot doesn't take the width of the label into consideration when resizing the plot.
Is there a way to maybe move the plot to the right before resizing to 3,3 so that there's room to scientific notation?

You can set the lmargin option:
set lmargin 10
(or whatever size doesn't crop the label).

Related

Line Profile Diagonal

When you make a line profile of all x-values or all y-values the extraction from each pixel is clear. But when you take a line profile along a diagonal, how does DM choose which pixels to use in the one dimensional readout?
Not really a scripting question, but I'm rather certain that it uses bi-linear interpolation between the grid-points along the drawn line. (And if perpendicular integration is enabled, it does so in an integral.) It's the same interpolation you would get for a "rotate" image.
In fact, you can think of it as a rotate-image (bi-linearly interpolated) with a 'cut-out' afterwards, potentially summed/projected onto the new X-axis.
Here is an example
Assume we have a 5 x 4 image, which gives the grid as shown below.
I'm drawing top-left corners to indicate the coordinates system pixel convention used in DigitalMicrgraph, where
(x/y)=(0/0) is the top-left corner of the image
Now extract a LineProfile from (1/1) to (4/3). I have highlighted the pixels for those coordinates.
Note, that a Line drawn from the corners seems to be shifted by half-a-pixel from what feels 'natural', but that is the consequence of the top-left-corner convention. I think, this is why a LineProfile-Marker is shown shifted compared to f.e. LineAnnotations.
In general, this top-left corner convention makes schematics with 'pixels' seem counter-intuitive. It is easier to think of the image simply as grid with values in points at the given coordinates than as square pixels.
Now the maths.
The exact profile has a length of:
As we can only have profiles with integer channels, we actually extract a LineProfile of length = 4, i.e we round up.
The angle of the profile is given by the arc-tangent of dX and dY.
So to extract the profile, we 'rotate' the grid by that angle - done by bilinear interpolation - and then extract the profile as grid of size 4 x 1:
This means the 'values' in the profile are from the four points:
Which are each bi-linearly interpolated values from four closest points of the original image:
In case the LineProfile is averaged over a certain width W, you do the same thing but:
extract a 2D grid of size L x W centered symmetrically over the line.i.e. the grid is shifted by (W-1)/2 perpendicular to the profile direction.
sum the values along W

Relationship between dpi and figure size

I have created a figure using matplotlib but I have realized the plot axis and the drawn line gets zoomed out.
Reading this earlier discussion thread, it explains how to set the figure size.
fig, ax = plt.subplots()
fig.set_size_inches(3, 1.5)
plt.savefig(file.jpeg, edgecolor='black', dpi=400, facecolor='black', transparent=True)
With the above code (other configurations removed for brevity), I do get a resulting image file with 1200 X 600 desired dimensions(should we say resolution too?) and desired file size.
The projected image is scaled out in an unusual way, annotations for example are enlarged. While I can set the size of the labels on the axis, the figure doesn't look proportional with respect to the scale since the bottom and right spines are large and so are the plotted lines.
The question, therefore, is, what configurations are going wrong?
Figure size (figsize) determines the size of the figure in inches. This gives the amount of space the axes (and other elements) have inside the figure. The default figure size is (6.4, 4.8) inches in matplotlib 2. A larger figure size will allow for longer texts, more axes or more ticklabels to be shown.
Dots per inches (dpi) determines how many pixels the figure comprises. The default dpi in matplotlib is 100. A figure of figsize=(w,h) will have
px, py = w*dpi, h*dpi # pixels
# e.g.
# 6.4 inches * 100 dpi = 640 pixels
So in order to obtain a figure with a pixel size of e.g. (1200,600) you may chose several combinations of figure size and dpi, e.g.
figsize=(15,7.5), dpi= 80
figsize=(12,6) , dpi=100
figsize=( 8,4) , dpi=150
figsize=( 6,3) , dpi=200
etc.
Now, what is the difference? This is determined by the size of the elements inside the figure. Most elements like lines, markers, texts have a size given in points.
Matplotlib figures use Points per inch (ppi) of 72. A line with thickness 1 point will be 1./72. inch wide. A text with fontsize 12 points will be 12./72. inch heigh.
Of course if you change the figure size in inches, points will not change, so a larger figure in inches still has the same size of the elements. Changing the figure size is thus like taking a piece of paper of a different size. Doing so, would of course not change the width of the line drawn with the same pen.
On the other hand, changing the dpi scales those elements. At 72 dpi, a line of 1 point size is one pixel strong. At 144 dpi, this line is 2 pixels strong. A larger dpi will therefore act like a magnifying glass. All elements are scaled by the magnifying power of the lens.
A comparisson for constant figure size and varying dpi is shown in the image below on the left. On the right you see a constant dpi and varying figure size. Figures in each row have the same pixel size.
Code to reproduce:
import matplotlib.pyplot as plt
%matplotlib inline
def plot(fs,dpi):
fig, ax=plt.subplots(figsize=fs, dpi=dpi)
ax.set_title("Figsize: {}, dpi: {}".format(fs,dpi))
ax.plot([2,4,1,5], label="Label")
ax.legend()
figsize=(2,2)
for i in range(1,4):
plot(figsize, i*72)
dpi=72
for i in [2,4,6]:
plot((i,i), dpi)

GraphicsMagick crop PDF

I've got a 8.5x11 PDF at 300dpi. It has a single UPC label in the top left corner of the PDF. Imagine that there could be 30 labels on a 1 sheet, but we just have 1 label.
I'm trying to crop the PDF to be just the size of the 1 label. So far I've got this
gm convert -density 300 single.pdf out.pdf
Which doesn't do any cropping. When I crop to say 300x100 it makes a 20MB file with 30000 pages.
I have not a clue how to use -crop to actually crop to the correct size. I need it to be 3.5inches by 1.125 inches.
Using the following input PDF (here converted to a PNG):
the following command will crop the label:
gm wiz.pdf -crop 180x50+1+1 cropped.pdf
This label is sized 180x50 pixels.
For an 8.5x11in PDF at 300 PPI you'd have a 2450x3300 pixels PDF (which I doubt you do, but that's another question) and you'd need to use -crop 1050x337+0+0 (more exactly, 1050x337.5+0+0 -- but you cannot crop half pixels!).
Note, the +0+0 part crops the top left corner. If you need offset to the right by N pixels and to the bottom by M pixels use +N+M...
Using ImageMagick instead...
You could also use ImageMagick's convert command:
convert wiz.pdf[180x50+1+1] cropped.pdf
Comment about image sizes...
One additional comment about this remark:
"I have not a clue how to use -crop to actually crop to the correct size."
There is no other real size for raster images than pixels. ABC pixels wide and XYZ pixels high...
There is no such thing as an absolute, real size for a digital image that you can measure in inches... unless you additionally can state the resolution at which a given image is rendered on a display or a print device!
An 8.50x11in sized image at 300 PPI will translate to 2550x3300 pixels.
However, if your image does not contain this amount of pixels (which is the real, absolute size of any raster image), you may still be able to render it at 300 PPI -- but its size in inches will be different from 8.5x11in!
So, whenever you want to crop, use the absolute number of pixels you want. Don't use resolution/density at all on your command line!

disturbing artifacts in pdf

I'm struggling with a problem when making plots with filledcurves. Between the filled areas, there seems to be a "gap". However, these artifacts do not appear on the print, but depend on the viewer and zoom-options. In Gnuplot I use the eps terminal, the eps-files look great, but the lines appear when I'm converting to pdf. The conversion it either done directly after plotting or when converting the latex-document from dvi to pdf. As most of the documents are here on the display nowadays, this is an issue. The problem also appears when I'm directly using the pdfcairo terminal in Gnuplot, so it's not caused by the conversion (tried epstopdf and ps2pdf) alone.
I attached a SCREENSHOT of a plot displayed in "acroread" (same problem in other pdf-viewers).
Has anybody an idea how to get rid of it but keeping the graphic vectorized?
I just ran into the same issue. Apparently the filling between two curves
is done as a set of polygons that do not exactly touch one another, thus
the thin white lines visible on some PDF viewers.
One way to fix the issue is to draw over these polygon boundaries. First
define min and max functions in gnuplot:
min(x, y) = x < y ? x : y
max(x, y) = x > y ? x : y
Then, assuming that column 1 of "datafile" contains your x values and
that columns 2 and 3 contain the y values of curves 2 and 3, write:
plot "datafile" using 1:2:3 with filledcurves lc rgb "gray", \
"" using 1:2:(min($2, $3)):(max($2, $3)) with yerrorbars ps 0 lt 1 \
lc rgb "gray" lw 0.5
The first plot instruction fills the spaces between the curves in gray.
The second plot instruction draws points of zero size (ps 0) at each
x value (1) on curve (2) with thin (lw 0.5), continuous (lt 1), gray
(lc rgb "gray"), vertical errorbars (yerrorbars) from the lower to
the higher of curves 2 and 3.
This covers the white lines. To get best results you may need to
experiment with the thickness of the bars (e.g., lw 0.6, lw 0.2).
This issue is fixed with gnuplot 5.2, see https://sourceforge.net/p/gnuplot/patches/749/
The actual problem was, that filled curves were previously plotted as many quadrilaterals, which leads to artifacts (white stripes) in many viewers due to antialiasing.
Since version 5.2 filled curves are rendered as single polygon, which prevents these problems (see issue linked above).
The problem is still present in Gnuplot 5.0.4 and at least the cairolatex terminal which I use to output PDFs.
I also wanted to color the area between two curves, in my case defined as functions.
When I used something like
f(x) = 2 + sin(x)
g(x) = cos(x)
plot '+' using 1:(f($1)):(g($1)) with filledcurves closed
I got the same vertical white lines as in the question.
A simple solution for curves where one is always above the other is to let Gnuplot fill the area from the upper curve to the x-axis with the desired color and then paint it over with white from the lower curve downwards:
f(x) = 2 + sin(x)
g(x) = cos(x)
plot f(x) with filledcurves x1, g(x) w filledc x1 fs lc rgb "white"
Apparently this filledcurves style (not between curves but between a curve and an axis) avoids the trapezoid artifacts.
This can be readily extended for plotting data files and multiple stacked cures like in the question. Just paint from top to bottom and finish with white for the empty area between the lowest curve and the x-axis.
For overlapping curves a construction of minimum and maximum curves like in the answer from françois-tonneau might do the trick.
If you're talking about the red and cyan bits the gap could be an illusion caused by the Red + Cyan = White on a RGB screen. Maybe there's no gap, but the border areas appear as white due to the proximity of the pixels.
Take the screenshot and blow it up so you can see the individual pixels around the perceived gap.
If this is the case, maybe selecting a different colour scheme for the adjacent colurs would get rid of the effect. I certainly can't see anything matching your description on anywhere but the red and cyan bits.
From https://groups.google.com/forum/#!topic/comp.graphics.apps.gnuplot/ivRaKpu5cJ8, it seemed to be a pure Gostscript issue.
Using the eps terminal of Gnuplot and converting the eps file to pdf with
epstopdf -nogs <file.eps> -o <file.pdf>
solved the problem on my system. From the corresponding Man page, the "-nogs" option instructs epstopdf not to use Gostscript.

why the '.pdf' figure produced by gnuplot is large than matlab?

I used gnuplot to plot a stacked bar figure, the produced .pdf file is 50k. But the figure produced by matlab is 1-9k usually.
When I inserted the gnuplot-produced pdf figure in latex (pdflatex), and open the paper, the figure seems need re-produced (the stacked columns show one by one).
here is the command
----+
set style histogram rowstacked#errorbars gap 1 lw 3#clustered
set style data histograms
set bar
set term postscript eps color "Helvetica" 24
set output "file.eps"
plot
---+
the size of the output 'file.eps' is 26k. the size of 'file.pdf' produced by epstopdf is 65k.
Thank you.