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.
Related
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.
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.
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
I am new to Gui programming, so if this question has been repeated elsewhere using proper terminology I apologize.
Is it possible to make interactive geometric animations with matplotlib? In particular, I want to embed an interactive Matplotlib window within a Tkinter frame to test out several variants of the same algorithm.
Here is a typical usage scenario for which I want to write an interactive
program as described above: Say I want to test a triangulation algorithm for point-sets in the 2-d plane.
When I run my new_triangulation_algorithm.py script, I would like to open up an interactive tkinter frame having an embedded matplotlib window, where the user "mouses-in" his/her points by clicking on, say, 20 different points -- every time a point is selected, a thick blue dot appears at that position. I know Matplotlib "knows" the coordinates of the point when I hover my mouse cursor over it since I always see it displayed in the status bar of my plots.
But I don't know how to input a point at that position with a mouse.
The second panel of my Tkinter frame would then contain several buttons, each button corresponding a different triangulation algorithm which I would like to animate on a given point set.
As the algorithm proceeds, I would like the matplotlib window to get refreshed to show the current state of the algorithm. I presume I would have to use Matplotlib's animation feature to do this, but I am not sure about
this since Matplotlib will have to be embedded in a Tkinter frame.
In future, I would like not only to input points, but also segments, circles, rectangles, but I would want to master a basic example with points
as described above.
This example might be a start. Its backend independend. To add your own buttons you might want to have a look at matplotlibs NavigationToolbar class. There are backend specific implementations like NavigationToolbar2QTAgg. You could inherit the Tk version and add some controls.
from matplotlib import pyplot
import numpy
x_pts = []
y_pts = []
fig, ax = pyplot.subplots()
line, = ax.plot(x_pts, y_pts, marker="o")
def onpick(event):
m_x, m_y = event.x, event.y
x, y = ax.transData.inverted().transform([m_x, m_y])
x_pts.append(x)
y_pts.append(y)
line.set_xdata(x_pts)
line.set_ydata(y_pts)
fig.canvas.draw()
fig.canvas.mpl_connect('button_press_event', onpick)
pyplot.show()
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: