How to plot to a specific monitor when using multiple displays? - python

Does anyone know how to change the setting of plotting to the same monitor as the mouse cursor is to a specific monitor?
I have multiple monitors and one that is dedicated for graphs, but I always need to move my mouse there quickly to make sure that the plots appear there.
How can I fix this annoying issue?
Additional information that might be important:
The Python library is Matplotlib.
The display setting is "extended" mode.

I've found some workaround for this issue. Not an optimal solution, but worked for me.
I am using matplotlib backend: Qt5Agg
The workaround that I found is to move the window to a specific location and then maximize it. The location to move to would be anywhere within the display that you want the figure to appear in.
fig = plt.figure()
fig.canvas.manager.window.move(0,0)
figManager = plt.get_current_fig_manager()
figManager.window.showMaximized()
plt.plot(range(10))
plt.show()
In my case, I wanted the figures to be maximized anyway, but for those who don't want that, just moving the window using this function might be enough:
fig.canvas.manager.window.move(0,0)
The coordinates (0,0) were the corner coordinates of my main display. You can manually find what are the correct ones for your setup.
You can also set both, the position and the size of the figures manually using this approach:
fig = plt.figure()
mngr = plt.get_current_fig_manager()
posX, posY, sizeX, sizeY = (0,30, 1024, 768)
mngr.window.setGeometry(posX, posY, sizeX, sizeY)
plt.plot(range(10))
plt.show()
Thank you all for your replies.
If anyone finds a better solution, please post it here.

Related

Embedding a Matplotlib Graph into HTML

I am trying to build a website. One part of the website needs that a graph is show based on user input. It will be built using Django.
I have checked out a few options, mpld3 proving to be at least better than the others. The graph is kind of animated(?) as the scatter plots appear after a pause. This is a feature which would be great if I could include it.
So while using mpld3, I faced two problems:
1. When I run the python script, I have an image as a background for the graph. This does not appear when I use mpld3 to render it to a webpage.
2. Only the final plots appear. Is there a way that I can show the points coming up on the graph one by one with pauses as it is supposed to?
Here is part of the code with the necessary details. In case there's any further detail, I'll be glad to provide it.
fig, ax = plt.subplots()
im = plt.imread('map_main.png')
implot = plt.imshow(im)
plt.axis([0, width, 0, height])
plt.ion()
for i in locations:
x, y = locations[i]
plt.scatter(x, y, c='b')
plt.pause(0.05)
locations contain a bunch of coordinates where the scatter points are supposed to show up.
Any help on what I should study next to achieve this would be great. Thanks.

Specify Height and Width of zoomed Image in Matplotlib after plt.show()

I have a plotting routine and I show the result with
plt.show()
as this is the easiest way for me to see my data. Once I have found and area which I want to look at i want to plot the exact same area again for a different set of data which has the same xy dimensions. The easies way for me would be to see the coordinates of the corners after the zoom or the origin of the zoom and the size in xy direction.
I found this solution . If I understand it correctly I have to manually change the plotting script with the new x y limits for each subsequent plot I want to make.
Is there a possibility to show the limit of the manual zoom in the panel itself and have the possibility to perform and actual input in dedicated fields such that I can recreate this zoom?
Do you mean something like this?
This "Figure options" dialog is present in the Qt backend. To use it,
import matplotlib
matplotlib.use("Qt4Agg") # or "Qt5Agg" depending on the version

Programmatically setting matplotlib plot to initial zoom level [duplicate]

I want to display an image that is zoomed in when first shown, but still has the ability to zoom out to the full scale using the interactive "Reset original view" button in the figure toolbar. Cropping is completely unacceptable. Using plt.axis([x0, x1, y0, y1]) does allow panning but the interactive window will not reset to full scale.
Is there a way to trigger the plot to zoom or solve this issue another way?
A way to do this is:
fig, ax = plt.subplots(1, 1)
ax.imshow(np.random.rand(20, 20)
fig.canvas.toolbar.push_current() # save the 'un zoomed' view to stack
ax.set_xlim([5, 10])
ax.set_ylim([5, 10])
fig.canvas.toolbar.push_current() # save 'zoomed' view to stack
I am not sure how private push_current is considered and as I said in the comments this is being refactored for 1.5 (https://github.com/matplotlib/matplotlib/wiki/Mep22).
See https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/backend_bases.py#L2600 for how pan/zoom are implemented. The reason there isn't a 'zoom_window' command is for static images, you just use set_*lim.

Python on windows, open plot windows next to each other

I am using EPD-python2.7 on windows7. In my python program I end up creating 4-5 figures in separate plot windows. By default the plot windows get stacked on top of each other. Every time I have to drag and replace each of these windows away and distribute over the screen area.
(Q1) Is there any way to set it automatically to have plot windows created next to each other? As shown below in the attached image (it is the screenshot of my second external screen).
(Q2) I have a second (extra) screen, and ideally I would like to have the plot windows created next to each other the second screen, when every time I run my program
You can choose the location of your plot but it is dependant on backend. To check this,
import matplotlib
matplotlib.get_backend()
and then see this answer for various ways to adjust.
For example, this works for me on linux with Qt4Agg,
import matplotlib.pyplot as plt
#Choose the correct dimensions for your first screen
FMwidth = 1280
FMheight = 1024
#Choose the correct dimensions for your second screen
SMwidth = 1280
SMheight = 1024
fm = plt.get_current_fig_manager()
#Works with QT on linux
fm.window.setGeometry(FMwidth,0,SMwidth,SMheight)
This may be better for windows
fm.window.wm_geometry("+500+0")
You may also be able to get the screen size(s) from,
from win32api import GetSystemMetrics
width = GetSystemMetrics(0)
weight = GetSystemMetrics(1)
You can easily create a counter which increments whenever you create a plot and adjusts this specified position so the next plot is next to the previous one each time. However, the size and layout are much easier if you use subplots, for example to set up your 2 by 3 grid,
#Setup 2 by 3 grid of subplots
fig, axs = plt.subplots(2,3,figsize=(width,height))
axs[0,0].plot(x, np.sinc(x))
axs[1,0].hist(y)
etc
You can then use your counter to specify which plot you are currently using and increment this whenever you plot.
I had the same question. What wasn't obvious for me when I looked through the answers is that when you have a second monitor, you can get to it by just using coordinates that are relative to your first monitor. For example, I have a 4k monitor above my 1080p primary monitor, and I get put figures onto it by using negative values for the y position.
mgr = plt.get_current_fig_manager()
mgr.window.move(-400,-2000)
plt.show()
Apparently it knows my monitor arrangement from Windows.

imshow in subplot with interactive mode

I cannot get matshow() or imshow() to actually display the plot when both of the following conditions are true: (1) interactive mode is on: import matplotlib.pyplot as plot; plot.ion(), and (2) I am trying to use matshow on a specific subplot: fig = plot.figure(); ax = fig.add_subplot(111); ax.matshow([[1,2],[3,0]]).
Using plot.matshow([[1,2],[3,0]]) (note: no explicit axes) works find in interactive mode, but will always create a new figure window with a single axes object. The above code with the subplot also works fine without interactive mode using plot.show(), and will put the image on the correct axes.
More oddly, the above code with the subplot will show the image if I interact with the figure, such as by using the zoom tool and clicking randomly in the figure window (there is no visible axes object, but I just click somewhere in the middle of the figure window).
Any ideas what might be causing this, how I could fix it, or how I could get around it to use matshow or imshow on a specified subplot (the end use case is to have more than 1 subplot in the figure)? This occurs in python (2.7.6) and ipython (1.1.1)
This may have something to do with this documentation:
Display an array as a matrix in a new figure window.
However, you may as well use imshow with suitable arguments:
import matplotlib.pyplot as plt
plt.imshow(mat, interpolation='nearest', origin='upper', aspect='equal')
This should do the same thing while being a bit less odd. This is actually exactly what matshow does internally. It just adds a few tick markers to the image.
Also, by having a look at the source (or closely reading the help string), you may try to do:
plt.matshow(mat, fignum=0)
This should force it use current axis, which it picks by using gca.
In addition to this, there is ax.matshow which you used, as well. Actually plt.matshow is a very thin wrapper around ax.matshow, mostly to create the new image.
If you still have problems with matshow or imshow in subplots, please make a minimal complete example for us to try! Here is something I tried in the interactive shell (IPython):
figure()
ax = subplot(121)
ax2 = subplot(122)
ax.matshow(random.random((20,30)))
ax2.plot(linspace(-1,1,100), linspace(-1,1,100)**2)
draw()
(Could the problem be a missing draw?)
What I got:

Categories

Resources