Using PyQt4 and matplotlib I have connected a button click to perform some calculation and render a graph. The tight_layout() only applies after clicking the button a second time.
When I'm done setting up the axes and putting data on the graph, I call
fig.tight_layout()
fig.canvas.draw()
I've tried to fake a second button press without success:
from PyQt4 import QtGui
QtGui.QApplication.processEvents()
fig.tight_layout()
fig.canvas.draw()
QtGui.QApplication.processEvents()
fig.tight_layout()
fig.canvas.draw()
My thought was that the Qt surface wasn't recognized as dirty, but resizing the window redraws the chart with the same loose layout. The tight layout does apply when I clear the axes and repopulate the chart.
How can I make tight_layout() apply the first time the graph is drawn?
Seems like there's no need to explicitly call draw or processEvents. Instead, I just needed a call to canvas.updateGeometry().
Related
I have a plot that has a scatter. I was using previous answers that allowed me to click individual points of the scatter and display a label that I connected to each point (Found here and here). It worked well, but I now want to display a separate line on the same plot. I'm able to show the line, but now when I click on points near it, it displays a box about the line and not the scatter. I used zorder to have the scatter displayed on top but that doesn't change anything about which plot is selected when I click. Is there a way to specify which plot is on top in the mplcursors? I would think there would be a way if I wasn't using the loop to connect the scatter plot points with the labels, but I'm not sure if there's another way to do that. Alternatively, is there a way I could tell mplcursors to just ignore the line altogether?
Code snippet:
fig = plt.figure(figsize=(7,4))
ax = fig.add_subplot(1,1,1)
ax.plot(x_axis_2, y_axis_2, zorder=0) #This is the line
for i in self.full_dict['full_results']: #This is for the scatter plot
ax.scatter(i[1],i[2],label='$[1D,2D]: {}$'.format(i[0]),zorder=5)
canvas = FigureCanvasTkAgg(fig, master=self.root)
canvas.draw()
canvas.get_tk_widget().grid(row=14,column=0,ipadx=40,ipady=10,columnspan=6)
datacursor(formatter='{label}'.format)
I am facing couple of issues. First, I wanted all the plots in a separate window. For this, I successfully changed the settings and I got the separate window. The problem is, I got all the plots in same figures, which is bad. Second issue is, how do I inscribe window pan to the Ipconsole? I donot want a separate window. I want this window inside the console?
For the first issue, you can have your plots in different figures by using figure this way:
import matplotlib.pyplot as plt
plt.figure()
# Plot your first graph(s)
plt.figure()
# Plot your other graph(s)
plt.show()
Each time you call figure, a new window is created. For more information on figure, you can check the doc
I'm using matplotlib to show a picture but I want to hide the window frame.
I tried the code frameon=False in plt.figure() but the window frame is still there. Just the background color turns to grey.
Here is the code and running result. The picture was showing with the window even I add the "frameon=False" in the code.
frameon suppresses the figure frame. What you want to do is show the figure canvas in a frameless window, which cannot be managed from within matplotlib, because the window is an element of the GUI that shows the canvas. Whether it is possible to suppress the frame and how to do that will depend on the operating system and the matplotlib backend in use.
Let's consider the tk backend.
import matplotlib
# make sure Tk backend is used
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
# turn navigation toolbar off
plt.rcParams['toolbar'] = 'None'
# create a figure and subplot
fig, ax = plt.subplots(figsize=(2,2))
#remove margins
fig.subplots_adjust(0,0,1,1)
# turn axes off
ax.axis("off")
# show image
im = plt.imread("https://upload.wikimedia.org/wikipedia/commons/8/87/QRCode.png")
ax.imshow(im)
# remove window frame
fig.canvas.manager.window.overrideredirect(1)
plt.show()
I'm using matplotlib to show a picture but I want to hide the window frame.
I tried the code frameon=False in plt.figure() but the window frame is still there. Just the background color turns to grey.
Here is the code and running result. The picture was showing with the window even I add the "frameon=False" in the code.
frameon suppresses the figure frame. What you want to do is show the figure canvas in a frameless window, which cannot be managed from within matplotlib, because the window is an element of the GUI that shows the canvas. Whether it is possible to suppress the frame and how to do that will depend on the operating system and the matplotlib backend in use.
Let's consider the tk backend.
import matplotlib
# make sure Tk backend is used
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
# turn navigation toolbar off
plt.rcParams['toolbar'] = 'None'
# create a figure and subplot
fig, ax = plt.subplots(figsize=(2,2))
#remove margins
fig.subplots_adjust(0,0,1,1)
# turn axes off
ax.axis("off")
# show image
im = plt.imread("https://upload.wikimedia.org/wikipedia/commons/8/87/QRCode.png")
ax.imshow(im)
# remove window frame
fig.canvas.manager.window.overrideredirect(1)
plt.show()
I am using matplotlib with interactive mode on and am performing a computation, say an optimization with many steps where I plot the intermediate results at each step for debugging purposes. These plots often fill the screen and overlap to a large extent.
My problem is that during the calculation, figures that are partially or fully occluded don't refresh when I click on them. They are just a blank grey.
I would like to force a redraw if necessary when I click on a figure, otherwise it is not useful to display it. Currently, I insert pdb.set_trace()'s in the code so I can stop and click on all the figures to see what is going on
Is there a way to force matplotlib to redraw a figure whenever it gains mouse focus or is resized, even while it is busy doing something else?
Something like this might work for you:
import matplotlib.pyplot as plt
import numpy as np
plt.ion() # or leave this out and run with ipython --pylab
# draw sample data
fig = plt.figure()
ax = fig.add_subplot(111)
line, = ax.plot(np.random.rand(10))
class Refresher:
# look for mouse clicks
def __init__(self, fig):
self.canvas = fig.canvas
self.cid = fig.canvas.mpl_connect('button_press_event', self.onclick)
# when there is a mouse click, redraw the graph
def onclick(self, event):
self.canvas.draw()
# remove sample data from graph and plot new data. Graph will still display original trace
line.remove()
ax.plot([1,10],[1,10])
# connect the figure of interest to the event handler
refresher = Refresher(fig)
plt.show()
This will redraw the figure whenever you click on the graph.
You can also experiment with other event handling like
ResizeEvent - figure canvas is resized
LocationEvent - mouse enters a new figure
check more out here:
Have you tried to call plt.figure(fig.number) before plotting on figure fig and plt.show() after plotting a figure? It should update all the figures.