I am using IPython Notebook to make some plots. For most of them I use
%matplotlib inline but for a few I change to %matplotlib notebook to be able to zoom in and stuff like that.
Now to the problem, the window displaying my plot (independent of what matplotlib setting I am using) suddenly became much smaller. Not the figure itself, just the window. I am really confused why this happened, if it was beacause I was switching between the two matplotlib settings or something else I made by mistake.
It is really annoying since I have to scroll in the window to se my whole figure unless I want to minimize it a lot. So if you have any idea how to make the plot window larger, please enlighten me.
Here you can se an example of what I mean by window: Small window. The 'window' according to me is where you can see "Figure 1" and the red button and ends where it cuts my plot.
Click to expand fully and show smaller. Double click to completely collapse it.
Related
I have tried a bunch of stuff over the last few months to only find the best way is as per the attached image which is to use a fixed container in the window to then carry on as per normal but it then makes it hard to have everything else resize properly.
Just curious if there would happen to be a better way to have the drawing area behind everything else to draw on with out having to use a "fixed" container.
In trying over the last few months if I use say a table then put a drawing area in it fills on of the boxes which is not how i feel it should work for what i am trying to do.
I have found it hard as if i try to resize the window I then have to resize the "fixed" container which is ok but if I try to make the window smaller by the bottom right corner it will not resize, I got round this by hard coding a window size and linking this to a button to "minimize" the window correctly.
If anyone has any pointers to information or has any help to offer that would be great.
If nothing comes up I guess I will keep trying to make it happen as I have worked out so far and have a minimum window size and maximum window size with maybe a x/y input box to customize the window size if required.
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.
I'm using PyQt5 (5.13.1) in python 3.7.4
I'm using macos for now (10.14.5) on an imac with one retina display and one non-retina display
I'm plotting a graph using matplotlib inside a scroll area
I've encountered a strange issue. I do not know if posting any code would be useful, but if you think some specific code will help, please let me know what code and i'll post.
here is the weird issue:
On the non-retina monitor, everything works fine. I can scroll up and down and see my graph and other scroll content. When I save the scroll area widget to an image, it is nice. All content is there. But, of course the resolution isn't great because it's the non-retina display.
On the retina monitor, as I scroll down, the bottom of the graph starts to disappear. and more disappears the more I scroll. The saved image looks exactly the same: whatever has disappeared on the screen is actually missing in the image (even though saving the whole scroll area should not do that, and in fact this error does not happen on the non-retina monitor or for content on the retina monitor that is not the matplolib graph. So, just to be clear, the issue is that matplotlib graphs seem to disappear at they are scrolled on my retina monitor.
As you can see from the images, the part of the graph that disappears starts at the bottom, not the part that is no longer visible because of scrolling.
scroll window on non-retina display. no problems
after dragging window to retina display, the bottom of the figure (from the x-axis) begins to disappear
So, does anyone know about this matplotlib issue? is there a setting that I seed to implement?
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.
I have been having some trouble with matplotlib since I started using python. When I use the interactive mode, I have to run ipython --pylab --wthread to get plots (if I don't use the --wthread command, it does not plot anything). So far, it hasn't been a problem.
Now, I want to:
Enter a loop
Plot something. This plot is a big plot with two subplots.
AFTER, show a button pannel with easygui to let the user decide depending on what he sees on the plot
close the plot
repeat for each thing to plot in my list.
I am finding several difficulties right now with this:
1) if I try to run the script in an interactive way using the run script.py command, then it does not plot annything, but directly jumps to the button pannel thing. However, if I stop the script, the plots appear. I am pretty sure that what is happening is that the "run" command does not show plots untill the script is done with the for loop. But I need the plots to appear before the buttons.
2) After some tries, I found this code to work (for some mystical reason to me...). I have tried other ways, but removing any of the show() or draw() commands just make the script not to work
fig=plt.figure(figsize=(16,8))
plt.show()
ax1=fig.add_subplot(121)
ax2.things...
ax2=fig.add_subplot(122)
ax2.things
plt.draw()
plt.show()
plt.draw()
showthebuttonsthing...
Even if this is working, matplotlib seems not to get along well with loops, and after 5 seconds of not pressing any button an just waiting, my matplotlib window gets grey. This might sound as something stupid, but colors are important for the decision I want the user the make...
3) I can't find a way to make a python script show plots if I run the python script outside ipython...
I guess there is something really wrong with my matplotlib configuration, but can't find a way to make this work...can anyone give me an hand on this?
Thanks a lot in advance!
It looks like you've almost got it, but try doing things in this order instead:
fig = plt.figure(figsize=(16,8))
ax = [fig.add_subplot(121),fig.add_subplot(122)]
ax[0].things
ax[1].things
plt.show()
#show the button panel
However, the best method may be to integrate the plot into your GUI. I am not familiar with EasyGUI, but it seems to be based on tk. This example should help you with embedding the figure into a tk window.