I would like to add to the height of the toolbar, but I cannot figure it out.
I have a figure showing a scatterplot and a color bar beside it. When I hover over the color bar a line gets added to the coordinates displayed inside the toolbar which adds some height to the toolbar. This then changes the sizes of the plot and the color bar. If I remove my cursor from the color bar the extra line gets removed and the height returns to its original size (which creates a very annoying flickering effect).
The issue started when I added a button to the toolbar using this code.
from tkinter import *
from tkinter.ttk import *
import matplotlib as mpl
import matplotlib.pyplot as plt
plt.rcParams["toolbar"] = "toolmanager"
from matplotlib.backend_tools import ToolBase
class NewTool(ToolBase):
...
...
figure.canvas.manager.toolmanager.add_tool('New Tool', NewTool)
figure.canvas.manager.toolbar.add_tool("New Tool", "toolgroup")
plt.show()
If I can either make the font size of the coordinates inside the toolbar smaller or change the height of the toolbar, the problem would be solved.
Related
I try to make a line graph in tkinter using the data in the database but then the graph appears as black only in the GUI.
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
###------Show Information Using Graph-------###
graquery = '''SELECT Date, Amount FROM balance'''
CURSOR.execute(graquery)
graresults = CURSOR.fetchall()
Date = [result[0] for result in graresults]
Amount = [result[1] for result in graresults]
figure = plt.figure()
plt.plot(Date, Amount)
plt.xlabel('Date')
plt.ylabel('Amount')
plt.title('Balance graph Graph')
gracanvas = Canvas(main_WINDOW, width=1070, height=452)
gracanvas.pack()
gracanvas.place(x=356, y=270)
figure_canvas = FigureCanvasTkAgg(figure, canvas)
figure_canvas.draw()
change:
figure_canvas = FigureCanvasTkAgg(figure, canvas)
to the following:
figure_canvas = FigureCanvasTkAgg(figure, gracanvas)
Also change this:
figure_canvas.draw()
to this:
gracanvas.create_window(0, 0, window=figure_canvas.get_tk_widget())
It appears that you are attempting to show a graph created using matplotlib within a tkinter interface. The cause of the black graph could be due to a few factors.
It is necessary to confirm that the appropriate backend is being utilized to display the graph in tkinter. In the code provided, you have imported the correct backend, FigureCanvasTkAgg, which is used for displaying matplotlib graphs in tkinter.
It is important to ensure that the figure_canvas object is placed in the correct tkinter widget. In the code provided, you have created a Canvas widget and are attempting to display the figure_canvas object within it, but it seems that you are using the variable canvas instead of gracanvas. It is suggested to use gracanvas instead of canvas.
Lastly, in order to show the graph in your GUI, you should call the get_tk_widget() method on the figure_canvas object to obtain the tkinter widget that can be displayed.
I need the whole plot window to be transparent so that a chrome window, for example, on my desktop could be seen through the plot, so that I can add points to it while seeing what's behind it.
https://stackoverflow.com/a/45505906/13650485
The answer I've listed above is EXACTLY what I want to do, except my interactive system doesn't work with TK. I'd like to use Qt5Agg. When I run the code above, the system won't accept it -- it says QT5 is currently running. If I run it without QT already loaded, it creates a blank transparent window (yay!) but if I move it or click on the icon it turns opaque black without any plot. If I change tk to Qt5 it complains on lift. If I remove the "win" code, it has no transparency(obviously). I've tried adding everything I can think of to make the canvas transparent and I can change the color but not make it transparent.
import matplotlib
# make sure Tk backend is used
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
# create a figure and some subplots
fig, ax = plt.subplots(figsize=(4,2))
ax.plot([2,3,5,1])
fig.tight_layout()
win = plt.gcf().canvas.manager.window
win.lift()
win.attributes("-topmost", True)
win.attributes("-transparentcolor", "white")
plt.show()
When I made the changes suggested by: eyllanesc
I found within a vanilla Spyder 4.1.3 | Python 3.7.7 64-bit | Qt 5.9.6 | PyQt5 5.9.2 | Windows 10
In order to import QtCore I had to first
conda install pyqt
not enough, so then conda install pyqt5
and also conda update --all
When I did that, the code ran without errors. This is a better first result!, but I still only get the frozen mpl.fig window. This time, however, it is white. . . The console returns, but the mpl window hangs. Run again, a new frozen window. Restart and run again: same result.
I hope that this is a simple error; please teach this newby.
#eyllanesc
Revised: Python screen tracing application – needs a mostly transparent plot window.
I need the whole plot window to be transparent so that a chrome window, for example, on my desktop could be seen through the plot, so that I can add plot (x, y) points to it while seeing what's behind it.
Adding the command win.setWindowFlags(QtCore.Qt.FramelessWindowHint) did indeed make the window transparent, but it made the tool bar transparent, got rid of the title bar, and removed the ability to move or resize the window. It also made it so that the graph area was not sensitive to the mouse unless I was over the line. I added the facecolor attribute to the subplots command so I could see what was going on. As long as I put a non-zero value for either the fig-alpha or the ax-alpha, the graph is sensitive to the mouse over the whole area.
I need to be able to move and resize the window and would like to have the toolbar be opaque or at least sensitive to the mouse over the whole toolbar. Can you help with this? Thanks for past help!
## Python Code Fragment by Helen for Windows 10
## to test sequence creating plot with transparent
## background (to be used to trace and record xy pairs)
from PyQt5 import QtCore
import matplotlib
matplotlib.use("Qt5Agg") #define backend, must be before pyplot is imported
import matplotlib.pyplot as plt
# create a figure and a subplot
fig,ax = plt.subplots(figsize=(4, 2),facecolor=(1.,1.,0.,0.1)) #facecolor of figure
fig.patch.set_alpha(0.1)
ax.patch.set_alpha(0.1)
# plot some fixed points
ax.plot([2, 3, 5, 1])
fig.tight_layout()
#make window transparent to the desktop
win = plt.gcf().canvas.manager.window
win.setAttribute(QtCore.Qt.WA_NoSystemBackground, True)
win.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
win.setStyleSheet("background:transparent")
win.setWindowFlags(QtCore.Qt.FramelessWindowHint)
win.setWindowTitle("My App")
plt.show()
You have to use the Qt flags, tested on Linux:
from PyQt5 import QtCore
import matplotlib
# make sure Tk backend is used
matplotlib.use("Qt5Agg")
import matplotlib.pyplot as plt
# create a figure and some subplots
fig, ax = plt.subplots(figsize=(4, 2))
fig.patch.set_alpha(0.0)
ax.patch.set_alpha(0.0)
ax.plot([2, 3, 5, 1])
fig.tight_layout()
win = plt.gcf().canvas.manager.window
win.setAttribute(QtCore.Qt.WA_NoSystemBackground, True)
win.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
win.setStyleSheet("background:transparent")
plt.show()
I am aware that there are couple of questions on this around the web but unfortunately none of those helped me with this. My relevant matplotlib imports are:
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
Below is how I call for new plots:
self.myFig1 = Figure(figsize = (10, 4), tight_layout = True)
self.myPlot1 = self.myFig1.add_subplot(111)
self.myPlot1.plot([blah],[blah])
canvas1 = FigureCanvasTkAgg(self.myFig1, self.myFrame)
canvas1.show()
canvas1.get_tk_widget().grid()
I have a refresh button that sort of keeps calling the function that ends up creating this plot, but I need one embedded plot which is updated after every button click, not recreated. I have tried things like Figure.close(), Figure.clf() but none worked. I'd appreciate your help with this.
Additional info: The reason it keeps creating a new plot is because I keep .grid-ing it over and over again. So I deleted the .grid() part of the code and I tried something like this below which did not work:
self.myFig1.clf()
self.myFig1 = Figure(figsize = (10, 4), tight_layout = True)
self.myPlot1 = self.myFig1.add_subplot(111)
self.myPlot1.plot([blah],[blah])
canvas1 = FigureCanvasTkAgg(self.myFig1, self.myFrame)
canvas1.draw()
This just destroys the figure, canvas, everything and doesn't plot anything.
self.myFig.clear()
self.myPlot = self.myFig.add_subplot(111, **self.nadalkwArgs)
self.myPlot.plot([series1], [series2])
self.myFig.canvas.draw()
Is what solved my problem. Your "refresh plot" button or method should have this in order to keep the canvas, clear the old plot, make the new plot and keep plot style elements such as xlabel, ylabel etc. So basically, first you clear the figure(not the subplot, self.myPlot.clear() would clear the plot but you can't have your kwargs that way), and then you recreate the subplot with kwargs and then you plot, and finally you .canvas.draw()
There is no need to recreate a new canvas or fig.
After grid your FigureCanvasTkAgg, you can reset line in button callback only by:
self.myPlot1.set_data(xdata,ydata)
self.myFig.canvas.draw()
I have borrowed some code from another source and I want to edit the figure produced. Here is the relevant (i think) code from the script.
import gtk #the gui toolkit we'll use:
from matplotlib.figure import Figure
from Tkinter import *
from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas
#create a window to put the plot in
win = gtk.Window()
#connect the destroy signal (clicking the x in the corner)
win.connect("destroy", quit_app)
win.set_default_size(600,500)
#create a plot:
fig = Figure()
ax = fig.add_subplot(111,xlabel='Time Step', ylabel='Temp (deg C)', axisbg='black')
ax.set_ylim(0,100) # set limits of y axis.
canvas = FigureCanvas(fig) #put the plot onto a canvas
win.add(canvas) #put the canvas in the window
#show the window
win.show_all()
win.set_title("ready to receive data");
line, = ax.plot(times,yvals, color='red')
while(1):
line.set_ydata(yvals) # draw the line
fig.canvas.draw() # update the Canvas
win.set_title("Temp: "+str(yvals[49])+" deg C")
I don't know whether or not all the code above is necessary - but that is all the 'plot' related code I could find.
So anyway the code works in my program perfectly.
There are TWO tasks I would like to create:
(1) What I want is to include that 'str(yvals[49])' variable, which is currently being displayed in the title of the window, to be displayed in large font underneath the plot. So I think I need to make the window size a little bigger to accompany the text but not sure how to print it.
(2) I manged to change the background of the plot itself to black that plots a red line. But how can I change the background of the window itself to all black and the x/y axis to red as well.
Thanks!!
(1) What you are most probably looking for it the matplotlib text command. Have a look at http://matplotlib.org/users/pyplot_tutorial.html section working with text. It might be convenient to create two separate axes, so you can truly put the text below the whole figure. Maybe it is enough to place the text at xlabel position?
import matplotlib.pyplot as plt
plt.xlabel('yourtext')
(2) There are already good answers out there that might help you: e.g. How to change the pylab window background color?
As for the color of the axis Changing the color of the axis, ticks and labels for a plot in matplotlib
Have also a look at Matplotlib figure facecolor (background color) in case you want to save the figure.
I am using a Matplotlib plot (with Basemap) inside of a wxPython pane. I have got the plot (US map with scatter plot of cities). I am trying to do some interactive zoom capabilities (select a box on the map and "zoom" into that area only).
I have managed to get the toolbar to show, but when i click on the buttons, nothing happens. Seems like the toolbar is just there for show. Any Thoughts? Here is my code:
# Set up area for plotting Basemap Plot and scatter plot
self.figure = Figure(None,dpi=75)
self.canvas = FigureCanvas(self.PlotPanel, -1, self.figure)
self.axes = self.figure.add_axes([0,0,1,1],frameon=False)
self.SetColor( (255,255,255) )
# Toolbar Set up
self.toolbar=NavigationToolbar2Wx(self.canvas)
self.toolbar.Realize()
tw,th = self.toolbar.GetSizeTuple()
fw,fh = self.canvas.GetSizeTuple()
self.toolbar.SetSize(wx.Size(fw,th))
sizer_7.Add(self.toolbar,0)
self.toolbar.update()
Have a look at the embedding_in_wx2 example, which works fine for me.
Maybe there is something wrong with your imports: you first have to import matplotlib, than set the backend (matplotlib.use('WXagg')) and then import the backend.
However it isn't easy to help you without having a full example with all imports.