0

I am seeing my plots being 'distorted' when modifying exlusively the DPI of the figure. I thought that DPI had no effect whatsoever in the layout of elements within the figure/axes, so it would be great if someone could clarify this to me.

Here is a MWE: two figures are created with identical data and figure size, and they are rendered with different DPI (thus changing the pixel count). Notice that the legend box (and text size, I suppose?) in the higher-dpi version takes up more vertical space in the figure. In fact, for higher values (e.g. dpi=450) the legend box becomes taller than the actual axes area and the figure gets severely distorted...

import matplotlib.pyplot as plt
import numpy as np

x = np.array([1, 3, 5, 9, 11])
y_vals = [x*n for n in np.arange(0.5, 1.5, 0.1)]  # Random data for visualization purposes
dpi_lst = [150, 300]

for dpi in dpi_lst:
    fig = plt.figure(figsize=(4, 3), dpi=dpi)
    ax = fig.subplots()
    for n, y in enumerate(y_vals):
        ax.plot(x, y, label=f'Plot #{n}')
    ax.legend(loc='upper left')
    ax.set_title(f'DPI={dpi}')
    ax.grid()

plt.show()

These are the results: DPI=150 DPI=300

This might be another dpi VS figsize discussion, but reading this post and from my personal experience with matplotlib (other than legend boxes), I was under the impression that the figure size could change the inner layout of the figure but the DPI would only scale its render resolution.

This is problematic for me, since I am using live (interactive) plotting in my scripts to get the plots exactly like I want them, but then I am saving them in much higher resolution (DPI) for increased quality. Live plotting at high resolution is cumbersome to say the least: figures often do not fit in the entire screen for high enough resolutions. But I don't know how to preview my figures in lower resolution using the matplotlib interactive mode while keeping the exact same layout that the stored high-quality versions will have.

Thanks a lot to anyone willing to help!

EDIT (Added a line to the MWE to include the title, which I forgot)

In response to Lucas' answer, I checked the backend I was using and it is in fact Qt5Agg (print(matplotlib.rcParams['backend'])). I am using a recent release of matplotlib (3.5.3, since I had some issues with 3.6.0). When running the exact code shown above, I get the following plot windows (notice the different height of legend box):

Figure windows

Any clue on why my results may be different?

Arce11
  • 51
  • 1
  • 8

1 Answers1

1

I think what you need to do is preview your figures without specifying the dpi. And later on when you save them indicate the dpi you want.

more info regarding matplotlib.pyplot.savefig here

fig = plt.figure(figsize=(4, 3))
ax = fig.subplots()
for n, y in enumerate(y_vals):
ax.plot(x, y, label=f'Plot #{n}')
ax.legend(loc='upper left')
ax.grid()
plt.savefig("my_path.svg", dpi=300) # indicate here your dpi

EDIT

Regarding the distortion, I have not found any problem using your code and Qt support. I have even further increased the dpi on the figure and the maximum problem was the figure being bigger than the screen

enter image description here

Lucas M. Uriarte
  • 2,403
  • 5
  • 19
  • Please correct me if I'm wrong, but isn't DPI set automatically to 100 if not specified? I cannot try right now (will do as soon as I get a chance tonight/tomorrow morning). Did you try my MWE just removing the DPI option on figure creation? The issue is not just for figure saving, I don't think dpi should affect figure layout at all, whether in an interactive plot or a static renderer (e.g. saving to a file). – Arce11 Oct 07 '22 at 17:57
  • I have edited the answer, now you can see my output using your code on my computer and Qt as the backend. In my case, I do not think that there is a problem with distortions of the figure when increasing the dpi. – Lucas M. Uriarte Oct 07 '22 at 18:38
  • Please see my edit. I also have Qt as my backend, but there is the change in figure layout associated to the DPI change. Any clue on why this may happen? – Arce11 Oct 08 '22 at 00:10