3

I am trying to create axesless contour plot of my raster data. I managed to create the contour plot however I can't remove the axes completely. I can turn them off with plt.axis('off') but axes whitespaces are still there.

What I do:

cnt = plt.contour(my_data)
plt.clabel(cnt, inline=1, fontsize=10)
plt.axis('off')

Edit My output method

plt.savefig(image_path, transparent=False, bbox_inches='tight', pad_inches=0)

Results: Before plt.axis('off') enter image description here After plt.axis('off') There is still whitespaces on the left and bottom edges of the picture

I had the same issue with the imshow but I've managed to solve it here, however the same technique can't be used with contours.

So how can I plot contours without axes and any whitespaces they leave behind?

Edit So I managed to determine that the problem is not in 'plt.axis('off')' part of the code. The line does in fact completely remove the axes and it is visible when I call plt.show() however when I try to save the plot with 'plt.savefig()' I get that undesirable whitespaces. Why is that?

My code with output:

cnt = plt.contour(my_data)
plt.clabel(cnt, inline=1, fontsize=10)
plt.axis('off')
# no whitespaces
plt.show()
# whitespaces are present
plt.savefig(image_path, transparent=False, bbox_inches='tight', pad_inches=0)

Possible solution!? I did find the way to make my images almost what I wanted with:

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
plt.contour(data)
extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
plt.axis('off')
plt.savefig(image_path, transparent=False, bbox_inches=extent, pad_inches=0)

However I cant change the aspect ratio of the plot. I think that I do not understand this solution to the fullest.

Community
  • 1
  • 1
Domagoj
  • 1,674
  • 2
  • 16
  • 27
  • Just for my understanding: which whitespaces do you mean are left behind? Do you mean the white padding at the borders? – jkalden Dec 26 '14 at 14:36
  • I posted nontransparent pictures with the question. On them (by opening with any image browser) you can see the whitespaces I am talking about. However there is possibility that images have a small padding like in the imshow issue I linked. For me the biggest issue is the large whitespaces that are still on the places where the axis labels and ticks where. – Domagoj Dec 26 '14 at 14:42
  • Might `plt.tight_layout()` before `plt.show()` (or at the end in case of interactive mode on) solve your problem? – Imanol Luengo Dec 26 '14 at 17:39
  • @iluengo - `tight_layout` changes the size of the axes. Nothing more. The issues DomagojHack is having are because `savefig` overrides the figure's facecolor when saving. – Joe Kington Dec 26 '14 at 17:41
  • 1
    @JoeKington - It actually sounds like he wants to use tight_layout() also; the transparency point was also about the fact that it was not clear what was happening when it was posted. – David Manheim Dec 26 '14 at 20:56
  • @DavidManheim - Good point. After re-reading it, the two of you seem more on-track than me. – Joe Kington Dec 27 '14 at 00:54
  • @iluengo - well my first mistake was I did not specified my output method and I did not even try plt.show(). I use plt.savefig(image_path, transparent=False, bbox_inches='tight', pad_inches=0) which give me totally different results than plt.show(). – Domagoj Dec 27 '14 at 15:09

1 Answers1

2

This is actually due to savefig's defaults. The figure can have a transparent background (e.g. try fig.patch.set(facecolor='none'); fig.canvas.print_png), but it's being overridden when you call plt.savefig.

If you want a transparent background, you'll need to specify transparent=True in your call to savefig. Otherwise, it will override the figure's current background color and set it to opaque white.

Have a look at the documentation for savefig for more details.

As an example:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.random((5, 5))

fig, ax = plt.subplots()
cnt = ax.contour(data)
ax.clabel(cnt)
ax.axis('off')

fig.savefig('test.png', bbox_inches='tight', transparent=True)

enter image description here

Of course, this looks identical on this page, but if you open it up in an image viewer you'll notice that it has a proper transparent background:

enter image description here


Edit:

I may have misunderstood what you're asking. If you want the contour plot to take up the entire figure with no room left for tick labels, etc on the side, it's easiest to define the plot that way to begin with.

For example (note that this applies to any type of plot, not just contouring):

import numpy as np
import matplotlib.pyplot as plt

data = np.random.random((5, 5))

fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
cnt = ax.contour(data)
ax.clabel(cnt)
ax.axis('off')

plt.show()

enter image description here


If you're still having issues, it's probably because you're using fig.savefig(..., bbox_inches='tight'). That specifically requires the tick labels to be included in the saved image, even if they're invisible and outside of the bounds of the figure.

Try something similar to:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.random((5, 5))

fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
cnt = ax.contour(data)
ax.clabel(cnt)
ax.axis('off')

fig.savefig('test.png')
Joe Kington
  • 275,208
  • 71
  • 604
  • 463
  • Yes at first you misunderstand the question. I know how to create transparent and nontransparent version of the images. I mentioned transparency because on the transparent images that whitespaces are harder to spot, on contour plots. So the first part of this answer is not what bothered me. However after trying your answer from the edit I am getting the same result as with my first approach. Still, images with large whitespaces on the places where the axis labels and ticks would go if I dont call 'ax.axis("off")'. I determine there is a problem with 'plt.savefig' I use. I will edit my Q more. – Domagoj Dec 27 '14 at 14:51
  • 1
    @DomagojHack - Are you using `fig.savefig(..., bbox_inches='tight')`? If so, remove the `bbox_inches='tight'` and leave in the part that defines the axes as filling up the entire figure (`fig.add_axes([0, 0, 1, 1])`). `bbox_inches='tight'` will force `savefig` to include the axes ticks even if they're outside of the figure boundary and invisible. – Joe Kington Dec 27 '14 at 15:59
  • Thank you! That was the problem I see now. – Domagoj Dec 27 '14 at 16:40