How to zoom charts in jupyterlab - python

I am plotting some charts with a fixed size.
I need to keep this size because they are later saved and embedded in a Latex document.
While working in jupyter they look too small.
I know I can change the size with matplotlib but this is not my point. I just want jupyter to zoom them (even if that means lower resolution in my notebook).
Is there a way I can increase the size when they are shown without touching matplotlib sizes?

Related

How to increase matplotlib figure dpi without increasing the window size of the shown plot?

I want to increase the dpi of plots in matplotlib, but the window that displays the plot gets far too large when deviating from the default of
100. I've been using
import matplotlib
matplotlib.rcParams['figure.dpi'] = 300
matplotlib.rcParams['figure.figsize'] = (6.4, 4.8)
to increase the dpi of all plots shown and forcing it to have the default size but it still has the size issue. I would like it so that all plots displayed are uniform in size and dpi without having to individually set this for every figure. Any way to do this?
I think that this won't work as you wish for. The resolution (given in dpi) determines how many points an inch has. The size defines how many inches the figure should have. But none of both sets the number of pixels that your monitor should display for an inch. The thing is that matplotlib and python do not resize plots (only images). So if you save the plot as an image and open it again (with any image viewer) and you click on "show me 100% size", the figure will behave as you intended it to. But while drawing the pixels in a plot (that is what matplotlib does if you call matplotlib.pyplot.draw()), it needs to draw every pixel, which is why one might think that figuresize and dpi both result in a larger plot in matplotlib. Essentially figuresize tells the image viewer how to resize the image when displaying it.
I found this post is particularly useful for explaining the different behavior of size and resolution.

How can I scale inline matplotlib figures within JupyterLab?

I'm trying out JupyterLab having used Jupyter notebooks for some time. I use the standard %matplotlib inline magic at the start. I've noticed that JupyterLab displays matplotlib figures much larger than Jupyter notebooks used to.
Is there a way to force JupyterLab to display the images in smaller window/area? I know I can change the figsize I pass when creating the figure but that does not scale the text/labels within the figure and I end up with effectively oversize labels and titles.
Ideally within JupyterLab I'd like to be able to set it up so images fit in an area I can define the size of and if they're larger they get scaled to fit.
I've been reading the JupyterLab docs but nothing leaps out at me at solving this particular problem.
Update: I'm running JupyterLab in Chrome. Chrome displays images up to the full width of the browser window; if the window is smaller than that width that allows the full size of the image, the image is scaled to fit - this is fully dynamic, if you shrink the width of the window the image will rescale on the fly. I changed my figsize parameter (and carefully adjusted font sizes to work) and I got a reasonably sized figure in JuptyerLab. I noticed that when I saved this to a jpg and put that in a powerpoint doc is was quite small (3,2). So I enlarged it, but it became blurred. So I regenerated it with dip=1200. The figure in JuputerLab got bigger. So JupyterLab does not respect the figsize. It's making somekind of judgement based on the number of pixels in the image.
Update 2: This piece of code demonstrates that the Juptyer Lab front end doesn't display images according to the figsize parameter but the product of figsize and dpi (upto the width of the screen, after which it is scaled to fit, presumably by Chrome itself). Note that the font size you see on the screen scales only with dpi and not with figsize (as it should).
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
xys = np.random.multivariate_normal([0.0, 0.0], [[1.0,-0.5],[-0.5,1.0]], 50)
for figsize in [(3,2),(6,4)]:
for dpi in [25,50,100]:
fig = plt.figure(figsize=figsize, dpi=dpi)
ax = fig.add_subplot(1,1,1)
ax.scatter(xys[:,0], xys[:,1])
ax.set_title('figsize = {}, dip = {}'.format(figsize, dpi))
A work around is to work in Jupyter Lab generating figures at a low dpi setting but saving figures at a high dpi setting for publications.

Plot Graphs in separated window

I have a long Jupyter notebook code and there is many cells, which are redrawing the actual graph plot. When I am running cells after changing their contents I need to check the plot, but I always need to scroll up and down. I would prefer to watch the plot changes in separated window (I am using two monitors), so I will change the cell content, run the cell, and then just turn my head and see the plot - without any scrolling. Is there a way how to do that? I know it can be done by Spyder, but I want to do it in Jupyter notebook, since I use a lot of notebook advantages, such as Latex notes and headings between cells. Thanks a lot for any advice!
It would be great if you could tell us how you print your graph (what library ?). Ipython provide magic command. For example, if you use matplotlib to plot some figures, just add %matplotlib qt on top of your cell to make the plots appear in a separate window.
See the list of magic command available here.

Exporting Chaco plots to PDF

I want to save some Chaco plots to PDF (or another vector format such as EPS or SVG). I have already discovered PdfPlotGraphicsContext, but this suffers from two problems:
the PDF's page size is not adjusted to the size of the plot (requires a cropping post-processing step)
it doesn't seem to support transparency
Can these issues be worked around somehow, or is there an alternative way of exporting plots in a vector format?

matplotlib shows different figure than saves from the show() window

I plot rather complex data with matplotlib's imshow(), so I prefer to first visually inspect if it is all right, before saving. So I usually call plt.show(), see if it is fine, and then manually save it with a GUI dialog in the show() window. And everything was always fine, but recently I started getting a weird thing. When I save the figure I get a very wrong picture, though it looks perfectly fine in the matplotlib's interactive window.
If I zoom to a specific location and then save what I see, I get a fine figure.
So, this is the correct one (a small area of the picture, saved with zooming first):
And this one is a zoom into approximately the same area of the figure, after I saved it all:
For some reason pixels in the second one are much bigger! That is vary bad for me - as you can see, it looses a lot of details in there.
Unfortunately, my code is quite complicated and I wasn't able to reproduce it with some randomly generated data. This problem appeared after I started to plot two triangles of the picture separately: I read my two huge data files with np.loadtxt(), get np.triu(data1) and np.tril(data2), mask zeroes, NAs, -inf and +inf and then plot them on the same axes with plt.imshow(data, interpolation='none', origin='lower', extent=extent). I do lot's of other different things to make it nicer, but I guess it doesn't matter, because it all worked like a charm before.
Please, let me know, if you need to know anything else specific from my code, that could be relevant to this problem.
When you save a figure in png/jpg you are forced to rasterize it, convert it to a finite number of pixels. If you want to keep the full resolution, you have a few options:
Use a very high dpi parameter, like 900. Saving the plot will be slow, and many image viewers will take some time to open it, but the information is there and you can always crop it.
Save the image data, the exact numbers you used to make the plot. Whenever you need to inspect it, load it in Matplotlib in interactive mode, navigate to your desired corner, and save it.
Use SVG: it is a vector graphics format, so you are not limited to pixels.
Here is how to use SVG:
import matplotlib
matplotlib.use('SVG')
import matplotlib.pyplot as plt
# Generate the image
plt.imshow(image, interpolation='none')
plt.savefig('output_image')
Edit:
To save a true SVG you need to use the SVG backend from the beginning, which is unfortunately, incompatible with interactive mode. Some backends, like GTKCairo seem to allow both, but the result is still rasterized, not a true SVG.
This may be a bug in matplotlib, at least, to the best of my knowledge, it is not documented.

Categories