Increase resolution of figure for saving - python

Is there a way to increase the resolution of a figure when saving it using the matplotlib toolbar save button?
I tried increasing the dpi but it doesn't seem to make much of a difference when using the save button on the toolbar.
This is how I was increasing the dpi to what the user specified.
if self.txtDPI.toPlainText() == "":
DPI = 120
else:
DPI = int(self.txtDPI.toPlainText())
self.tempfig.set_dpi(DPI)
I have a GUI that the figure is on and underneath it is the matplotlib toolbar so they can edit the chart. I am trying to get it to save the figure with the set dpi when the user hits the "save" button on the matplotlib toolbar. I thought drawing the figure with the user input dpi would make it save the figure with that dpi but it doesn't. It also makes the chart go off the "canvas" if the user increases the dpi above 120.
EDIT:
I got it to work by doing the following:
import matplotlib as mpl
mpl.rcParams['savefig.dpi'] = DPI
Thank you for all your suggestions!

If you're happy to set the dpi before generating the figure then I would suggest setting the rcParams. This can be done either in a matplotlibrc file, or if you just have one script that you want to increase the dpi then add something like this:
import matplotlib.pyplot as plt
plt.rcParams['savefig.dpi'] = 500
If on the other hand you want to be able to set the dpi when you save the figure, then you will need to extend the interactive matplotlib window. Here is an example of how that can be done in matplotlib alone
EDIT:
An easy way to add the interactivity would be to make use of the IPython interactive widgets. Here is a screenshot of how this could work:
Every time you move the slider, it calls plot with the updated value of dpi, so the figure is resaved. If the figure is particularly large and slow to generate you may want to use interact_manual instead. In order to do this just install the IPython notebook with version greater than 3.0.

Related

The way to save figures with ppi using python

I am struggling with saving figures with ppi.
I know how to save figs with dpi and set figure size but have no idea with ppi.
When I search, I could know the dictionary definition but not related to setting codes.
If I want to set the figure size as 8cm*10cm with 2800 resolution in pixels (or 500ppi),
how can I set the figure and save figs?
The below code is the way I usually made.
e.g.
cm=1/2.54
fig=plt.figure(figsize=(8*cm,10*cm))
(my code)
plt.savefig('Name.jpg', dpi=300)
I tried to search the way to save figures in ppi, but most reviews were related to setting dpi with changed fig size.
I know they are connected each other but it was hard to understand how I can set the code.
I am expecting to make a code with fixed fig size and ppi.

Tkinter DPI bug depends on how import is entered?

I have a weird question. In essence: why does the way I enter the pyplot import line into iPython influence my plot?!
Try this (on Windows 10):
Use a high-DPI main monitor set to 200%
Start a fresh iPython console
Enter the three blocks of code below one by one, using any of these ways for any block:
just typing, OR
pasting: pressing Ctrl+V, OR
pasting: clicking the right mouse button, OR
pressing Up to get it from history
To execute each block, just press Enter
Check whether the whole axis is visible
Close iPython and try again
The minimal reproducible example:
import matplotlib as mpl
mpl.use('TkAgg')
import matplotlib.pyplot as plt
from ctypes import windll
windll.shcore.SetProcessDpiAwareness(2)
fig = plt.figure()
w = fig.canvas.manager.window
print(w.winfo_screenwidth(), w.winfo_screenheight())
w.wm_geometry('1600x800+60+0')
fig.canvas.flush_events()
plt.plot(1, 'x')
plt.show(block=False)
Now the result depends on how the first two blocks have been entered. If one or both of them used option 1 or 2, an incorrect monitor size is reported (1920x1080), but I do get a 'correct' plot (with tiny fonts):
If both import lines have been entered using option 3 or 4 however, the reported monitor size is correct (3840x2160), but I get incorrectly sized/zoomed plots (with normal font size):
The behavior depends on how import lines (or the 'run script' they are in) are entered!? Not how they are run, that's just Enter.
Any idea what causes this? Or how to fix it? Other than remembering to always do Ctrl+V instead of history or right click...
Is this a bug I can report somewhere?
Changing the window size manually a bit afterwards makes the axis fit inside the window. But I would like to script it. And the manual resize does not fix all differences: options 1 and 2 keep using tiny fonts.
Explicitly resetting SetProcessDpiAwareness(0) prevents the issue (1 and 2 keep it): monitor reported as 1920x1080, axes fit inside figure, but a larger window and normal size fonts.
Specifying dpi=192 (or something) explicitly with plt.figure() does not help or change anything.
The used backend is the TkAgg Windows default. The exact same happens with TkCairo. The WxAgg and QtAgg alternatives work ok, using window.SetClientSize(1600, 800) resp. manager.resize(1600, 800) (they work like SetProcessDpiAwareness(0)). So I guess the issue is specific to tkinter.
Using python.exe (instead of ipython.exe) always shows the incorrect version. AFAICS I have not changed the High DPI compatibility settings for iPython.
Almost all differences are gone when I do this:
fig.dpi = windll.user32.GetDpiForWindow(w.winfo_id()) / 0.96
This leaves w.winfo_screenwidth/height() halved and small tool buttons when using options 1 and 2. But the window is 1600 pixels wide as specified (758 resp. 728 high, due to the button bar), fonts are readable (200% as configured in Windows) and the axes fit inside the figure.
I must remember not to use dpi= with plt.figure(), because that messes things up again.
I'm still curious where the difference comes from, but this way I can use the default Tk backend without issues.

Python Pandas plot command produces small images on high resolution display

I am using the following line of code in my python application.
df['Close'].plot()
The figure produced by this code is very small on my high resolution display (Microsoft Surface Studio). I have looked at the documentation for the pandas plot command and matplotlib but have not found any relevant settings. Any help appreciated.
I would guess that you want to leave the figure size constant but change the dpi (dots per inch).
Somewhere on top of your script or notebook add
import matplotlib.pyplot as plt
plt.rcParams["figure.dpi"] = 144
Change 144 to your liking. (Note that multiples of 72 usually give nice lines).
The figsize parameter is what you're after.
df['Close'].plot(figsize=(20,10))
If you are in a Jupyter Notebook, there may be an issue where the notebook shrinks figures to fit in the cell output as .plot(figsize=x,y) increases the size. You will notice the text getting smaller but the plot seems to stay the same size, as you increase the figsize parameters.

Change figsize in matplotlib

It seems that the figsize option only changes the ratio of the height to width. Atleast this is the case when using jupyter notebooks. Here is an example:
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
plt.figure(figsize=(16,8))
plt.plot(np.arange(1,10),np.arange(1,10))
plt.show()
plt.figure(figsize=(24,6))
plt.plot(np.arange(1,10),np.arange(1,10))
plt.show()
I was hoping that figsize intended inches, not a relative ratio. How would you go about enforcing that in python/ jupyter notebooks.
If you use a large figsize, say figsize=(50, 5) you will notice that the lines, the labels, everything is incredibly thin and small with respect to a plot with normal size.
This happens because you are using widths that are not compatible with the width of the output cell
and the notebook just scales down the figure to make it fit in the output cell.
To have the behavior you asked for, you need a horizontal scrolling capability in the output cell. I don't know of a `nbextension` that can enable horizontal scrolling in output cells.
After a bit of experimenting, it looks like using the nbagg backend
%matplotlib nbagg
gives you a scrollable output cell, and an interactive one as well, inside the notebook and possibly it is what you want.
Addendum
I've found this issue on IPython's github, with a request for horizontal scrolling in output cell — as you can see it's dated 2012 and there is no followup of sort.
plt.gcf().set_size_inches(16, 8)
After change figsize the figure size do changed when the parameter in a certain range.In my condition,size not growing after size above (24,8).When it's still below the range the size do increase.It's base on your displayer dpi, you can set the dpi in figure but eventually it's rely on your hardware.
The figaspect is set by matplotlib.figure.figaspect
If you save figures to files use savefig,you will see the image size increase also.

IPython and Inline Matplotlib Figure Sizes

In my current iPython, matplotlib plots are being displayed inline. I wanted a way to display images with specific pixel sizes, as I usually only work with pixels and I don't print anything out.
My screen PPI is 208, so I ran these 2 pieces of code:
plt.figure(figsize=(2000/float(208), 1000/float(208)), dpi=208)
# other code here...
plt.savefig('my_fig.png', dpi=208)
What I'm confused about is this: When I examine my_fig.png, it is in fact 2000 pixels by 1000 pixels, this is what I want. Also according to https://stackoverflow.com/a/7912007/582917 the DPI settings for rendering to the display device and rendering a file have different defaults. That's why I have to also add in dpi=208 to the plt.savefig function.
However the image rendered on the iPython notebook, which is in the browser, is much smaller. Using my browser ruler, it's roughly 600 by 300 pixels.
Using the same DPI for both functions, why is that the inline rendered image in iPython notebook is so small, while my saved image is at the correct resolution that I want?
Note that I'm running iPython in a Virtualbox (that is also headless), I'm not sure if this can cause any differences.
After a few trial and errors, in order to get close the correct size for inline rendering, the figure dpi needed to be 58. But even then the images generated inline do not match exactly with my specified pixel count. It's always +- 10 to 20 pixels.
This might be due to the fact that %matplotlib inline by default will pass bbox_inches='tight' to plt.figure(...).
Try the following,
After calling%matplotlib inline, do
%config InlineBackend.print_figure_kwargs = {'bbox_inches':None}
then create your plot. Here's what it did for me:
Before
After

Categories

Resources