Plot is getting cutoff

I get good .eps and .png images cropped as expected with -A on my system via
gmt ps2raster GMTjl_j.ps -A -Teg

I generally used to remember, from old days when I used LaTeX a lot, that a .ps file was supposed to contain material correctly positioned on paper sheet-size pages and a specific orientation - as it was purposed for printing on real paper. In contrast, .eps was an image prepared for embedding into other documents, .eps could not have multiple pages and was not related to any specific paper size nor orientation, so .eps was rendered relative to the lower left corner as origin in a .[e]ps previewer in portrait orientation - as long as the image itself was correct.

I won’t pretend I really understand much though.

You mean that this doesn’t get you a clean non cropped png file?

psconvert GMTjl_j.ps -Tg -A -S
@"c:/programs/GMTDIR/gswin64c.exe" -q -dNOPAUSE -dBATCH -dNOSAFER -dSCANCONVERTERTYPE=2 -dMaxBitmap=2147483647 -dUseFastColor=true -dGraphicsAlphaBits=2 -dTextAlphaBits=4 -sDEVICE=png16m  -g2762x2657 -r300 -sOutputFile="GMTjl_j.png" "./psconvert_32800d.eps"

The crazy thing is that the png was obtained from the psconvert_32800d.eps (as the command above shows and you can confirm) but that eps is cropped(???)

We probably misunderstood each other. I run the command you shown above, psconvert GMTjl_j.ps -Tg -A -S, and get exactly the .png you shown above.

When using figure with ps as file format and not specifying a paper size via PS_MEDIA that cutting off of the image is to be expected as @Joaquim already pointed out. From the docs:

If no paper size is specified via PS_MEDIA then GMT will default to A4 […] Note that any other graphics formats specified with ps will also not be cropped.

Source: figure — GMT 6.6.0 documentation

When I play around with the example scripts @chhei and @Joaquim provided I get the cut off plots as expected. Opening them in my vector graphics program I get the complete plot extending beyond the A4 canvas but everything is there. Maybe something special in the way Inkscape handles .(e)ps files?

For me both of @Joaquim psconvert calls work flawlessly. That’s with GMT version 6.6.0_d317a5d_2025.01.10 and Ghostscript version 10.04.0 on macOS.

Long time ago I know that Inkscape used ghostscript to convert PS to SVG. Don’t know how it works nowadays that GS dropped SVG, but apparently the same issue with not being able to show the full display of a valid eps file is still transposed into Inkscape.

And anyone knows how to set the PS_MEDIA in modern mode?

To set PS_MEDIA in modern mode just add --PS_MEDIA=VALUE to any GMT program. For example:

gmt coast -R-155.72/-155.62/19.45/19.55 -JM8i -Ggray -Bafg --PS_MEDIA=a2 -ps lixo

Ah, but that’s a one-liner (have I ever said that all GMT commands should be reducible to one-liners?)

I was thinking in the Yvonne’s example. I couldn’t find a way of setting it here.

gmt begin
gmt figure test_with_ps ps,pdf,png
gmt basemap -R-155.72/-155.62/19.45/19.55 -JM8i -Bafg
gmt end

Just add it to the basemap call in Yvonnes example:

gmt basemap -R-155.72/-155.62/19.45/19.55 -JM8i -Bafg --PS_MEDIA=a2

Thanks. It’s pretty obvious that I’m not a modern mode user.

gmt begin test_with_ps
gmt set PS_MEDIA a2
gmt figure test_with_ps ps,pdf,png
gmt basemap -R-155.72/-155.62/19.45/19.55 -JM8i -Bafg
gmt end

I agree that works on a single plot. However, the problem persists (cutoff plot) if you shift the y axis and create another plot:

import pygmt
region = [-155.72,-155.62,19.45,19.55]
proj = 'M8i'
color='lightblue'
fig = pygmt.Figure()
pygmt.config(PS_MEDIA="A2")
fig.coast(region=region, projection=proj, land='gray', water='skyblue', frame=True)
with fig.shift_origin(yshift='-4.1i'):
    fig.basemap(region=[0,10,0,10], projection='X8i', frame=True)
fig.show()

In fact, of you change yshift in shift_origin to -8.1i, then it plots as if the shifted plot is not there at all. Seems like the shift_origin isn’t setting the bounding box in a way that this version of Ghostscript recognizes it?

test.pdf (6.1 KB)

maybe my suggestion is stupid and random, but your figure appears in landscape orientation. Could you try adding pygmt.config(PS_PAGE_ORIENTATION="portrait")?

I’ve been breaking my head with this. To start with, it annoys me that PS files are not processable, though I also know why. We start with a PS and if we want to stay is the postscript family an eps is given to us. But than came this stupid thing of eps views being cropped by ghostscript.

So, in the psconvert-no-file-dup branch I was able to mitigate this a bit, but it only works in Classical mode (see comments on that branch for a short on why the modern mode is much more complicated). With that branch we can now do

gmt pscoast -R-155.72/-155.62/19.45/19.55 -JM8i -Ggray -Bafg -P > lixo.ps
psconvert lixo.ps -Tp -A

or 

psconvert lixo.ps -Tp -A -!

and get the full image well cropped and fully displayed by gs.

That’s not how it works. BB is always sufficiently big (11 m x 11 m) to accommodate the entire fig. But I don’t know what is happening inside PyGMT.

1 Like

Thank you for the suggestion. There was no change to the clipping problem when adding that in.

Interestingly, if you use xshift instead of yshift, the bounding box is resized to the right and there is no cropping. So the issue, at least in my environment, is restricted to cropping in the vertical direction.

If you do not set a PS_MEDIA, in modern mode (and hence PyGMT) the concepts of Portrait and Landscape have no meaning. Remember that we are cropping (psconvert -A) from a wall size.

When you set the PS_MEDIA to A2 or anything, the plotting origin is 1 inch by 1 inch off the lower left corner. So, for your 2nd basemap, you can’t shift the plotting origin downward.

Had a thought/guess. Do not run this last command and go to your ~/.gmt/sessions/???`

Sorry, wrote this last night but it apparently didn’t go through.

But as I was saying, pick the .ps- file in there, zip it and attach here.

Here you go!
test.ps (28.8 KB)

Here’s what I get after finishing the PS file and run

gmt psconvert test.ps -Tg -A

The file is clipped at bottom for the reason that Dondong cleverly remembered. In modern mode the origin is 20 cm from lower left corner, but when we set a page size we fall back into classic origin, which is only 2.5 cm so if you shift negatively you fall off the paper border.

Note, to close the ps file you need to add these lines at the bottom of the ps file.


grestore
PSL_movie_label_completion /PSL_movie_label_completion {} def
PSL_movie_prog_indicator_completion /PSL_movie_prog_indicator_completion {} def
%PSL_Begin_Trailer
%%PageTrailer
U
showpage

%%Trailer

end
%%EOF

But the original problem, if I understood it well, happened when no paper size was set. That’s the one you have to tackle now because this works as expected.

Sure enough, if I set a PS_MEDIA to something quite large and then shift the origin upward, I can get the entire plot to render. This works for me as a workaround:

import pygmt
fig = pygmt.Figure()
pygmt.config(PS_MEDIA="A0")
with fig.shift_origin(yshift='6i'):
    fig.coast(region=[-155.72,-155.62,19.45,19.55], projection='M8i', land='gray', water='skyblue', frame=True)
    with fig.shift_origin(yshift='-4.5i'):
        fig.basemap(region=[0,10,0,10], projection='X8i/4i', frame=True)
fig.show()

If I don’t set the PS_MEDIA, then the top of the plot is cropped since I’m shifting the origin 6 inches upward.