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
Related
I have a retina MacBook and I would like to display plots in Matplotlib that are high-dpi so that the plots don't look blurry on my screen.
When using set_matplotlib_formats and setting it to svg, everything looks perfect: the image is crisp and scalable, and the text size looks fine. However, scalable graphics are often not convenient when I'm making a plot that has hundreds of thousands of elements.
Setting it to png with a dpi of 300 doesn't work well since it makes the image bigger. The image is also not crisp—although the plot is rendered at high dpi, is it displayed quite large and thus the displayed dpi is low.
Trying retina seems to fix this issue (the plot size is correct and the image is crisp). However, it makes the text size really small (compare it to the svg option):
Is there an option that sizes the plot and the text correctly like svg but which doesn't use scalable graphics? Here is the code for reference:
import matplotlib
import matplotlib.pyplot as plt
from IPython.display import set_matplotlib_formats
%matplotlib inline
set_matplotlib_formats('retina')
plt.plot(range(5))
plt.show()
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.
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.
I'm working on image analysis and would like to display many variations on manipulations to an image.
When I use matplotlib.pyplot the images automatically shrink to the screen size. I prefer they reach below the screen and be scroll-able.
In bokeh the images are in poor resolution and after a certain amount of images the browser shows a blank due to memory issues:
Uncaught RangeError: Source is too large
layout.html:189 'CanvasRenderingContext2D.webkitImageSmoothingEnabled' is deprecated. Please use 'CanvasRenderingContext2D.imageSmoothingEnabled' instead.
I ended up using mpld3
pip install mpld3
and replace pyplot.show() with mpld3.show()
super simple
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.