matplotlib graphs not displaying on tkinter window - python-2.7

When I try to graph something with matplotlib in a tkinter window, it simply won't show up. If I remove the tkinter specific part, and just do a basic plt.plot(...) and plt.show() it shows up in my regular text output field. However, in this case I would like it to show up in a tkinter window. I Believe its because I am running this on a mac (macOS 10.12.4), however I cannot figure out how to get it to show up in the tkinter window.
import numpy as np
import Tkinter as tk
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
root = tk.Tk()
fig = plt.figure(1)
t = np.arange(0.0,3.0,0.01)
s = np.sin(np.pi*t)
plt.plot(t,s)
canvas = FigureCanvasTkAgg(fig, master=root)
plot_widget = canvas.get_tk_widget()
def update():
s = np.cos(np.pi*t)
plt.plot(t,s)
plt.show()
plot_widget.grid(row=0, column=0)
tk.Button(root,text="Update",command=update).grid(row=1, column=0)
root.mainloop()
As I said, I believe its due to the fact that I am running on MacOS. Also FYI when I run this a blank tkinter window shows up with the update button, but no graph. The Graph DOES however show up in the regular text output but I want it in the tkinter window for a GUI. Please Help!

You need to update the figure that is already in the tk canvas, instead of showing a new one with plt.show(). In this case there is only one figure open, so plt.plot() will actually work (although it might fail in more complex scenarios). What remains is to redraw the canvas, fig.canvas.draw_idle() after plotting.
import numpy as np
import Tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
root = tk.Tk()
fig = plt.figure(1)
t = np.arange(0.0,3.0,0.01)
s = np.sin(np.pi*t)
plt.plot(t,s)
canvas = FigureCanvasTkAgg(fig, master=root)
plot_widget = canvas.get_tk_widget()
def update():
s = np.cos(np.pi*t)
plt.plot(t,s)
fig.canvas.draw_idle()
plot_widget.grid(row=0, column=0)
tk.Button(root,text="Update",command=update).grid(row=1, column=0)
root.mainloop()
For the future and to be on the save side, try to avoid using pyplot when embedding matplotlib into GUIs. This prevents you from having issues like the one reported here.
import numpy as np
import Tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
root = tk.Tk()
fig = Figure()
ax = fig.add_subplot(111)
t = np.arange(0.0,3.0,0.01)
s = np.sin(np.pi*t)
ax.plot(t,s)
canvas = FigureCanvasTkAgg(fig, master=root)
plot_widget = canvas.get_tk_widget()
def update():
s = np.cos(np.pi*t)
ax.plot(t,s)
fig.canvas.draw_idle()
plot_widget.grid(row=0, column=0)
tk.Button(root,text="Update",command=update).grid(row=1, column=0)
root.mainloop()

Related

Django matplotlib: fname must be a PathLike or file handle

I am trying to display a plot with matplotlib and django following this and this questions, however it seems not working, I tried both solutions and only while using IO i get an empty canvas, but when I try to plot a 'real' plot I get the error in the title.
This is my view:
import django
from matplotlib.backends.backend_agg import FigureCanvasAgg as
FigureCanvas
from matplotlib.figure import Figure
import numpy as np
import matplotlib.pyplot as plt
import io
def mplimage(request):
fig = Figure()
canvas = FigureCanvas(fig)
x = np.arange(-2, 1.5, .01)
y = np.sin(np.exp(2 * x))
plt.plot(x, y)
buf = io.BytesIO()
plt.savefig(buf, format='png')
plt.close(fig)
response = django.http.HttpResponse(content_type='image/png')
canvas.print_png(response)
return response
and here the link in urls.py:
import mpl.views
url(r'mplimage.png', mpl.views.mplimage)
This works if you save the file objects as JPEG (requires PIL) instead of PNG using print_jpg() method instead of print_png().
Change:
response = django.http.HttpResponse(content_type='image/png')
canvas.print_png(response)
To:
response = HttpResponse(content_type='image/jpg')
canvas.print_jpg(response)
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
import numpy as np
import django
def showimage(request):
fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
x = np.arange(-2,1.5,.01)
y = np.sin(np.exp(2*x))
ax.plot(x, y)
response = HttpResponse(content_type='image/jpg')
canvas.print_jpg(response)
return response

Update image on a label PyQT5

I am new in python. I want to update an image on label1. But function 'def browse' always give me blank label instead. Seems the code does not get the image or it failed to update the label, and the program did not give any error message. Did i missed something here? Also, print command below setPixmap command is executed. i am using python 2.7 and PyQT4.
Thanks in advance
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import os, sys
import cv2
from PIL.ImageQt import ImageQt
class GuiCakep(QtGui.QWidget):
global label1, label2
def __init__(self):
super(GuiCakep, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(100, 100, 1000, 600)
self.setWindowTitle('Single Browse')
self.label1 = QtGui.QLabel(self)
self.label1.setFrameShape(QtGui.QFrame.Box)
self.label1.setGeometry(QtCore.QRect(20, 10, 451, 451))
pixmap = QPixmap('1stimage.jpg')
self.label1.setPixmap(pixmap)
self.label2 =QtGui.QLabel(self)
self.label2.setFrameShape(QtGui.QFrame.Box)
self.label2.setGeometry(QtCore.QRect(481, 10, 451, 451))
btn = QtGui.QPushButton('Browse', self)
btn.resize(btn.sizeHint())
btn.clicked.connect(self.browse)
btn.move(775, 500)
self.show()
def browse(self):
filePath = QtGui.QFileDialog.getOpenFileName(self, 'a file','*.jpg')
fileHandle = open(filePath, 'r')
pixmap = QPixmap('filePath')
self.label1.setPixmap(pixmap)
print("Whoa awesome")
def main():
app = QtGui.QApplication(sys.argv)
w = GuiCakep()
app.exec_()
if __name__ == '__main__':
main()
You are creating a Pixmap with 'filePath' as argument. This is a string, not your variable filePath.
Remove the both ' and this should update the label.

How to make tabular legend using matplotlib and python

I am plotting a choropleth map in python from a shapefile and i want to customize the legend of the plot, i am using the code bellow:
import pandas as pd
import pysal as ps
import geopandas as gp
import numpy as np
import matplotlib.pyplot as plt
pth = 'outcom.shp'
tracts = gp.GeoDataFrame.from_file(pth)
ax = plot_dataframe(tracts, column='Density', scheme='QUANTILES', k=4, colormap=plt.cm.Blues, legend=True)
plt.show()
Besides, i am using a small patch that i found here http://nbviewer.ipython.org/gist/jorisvandenbossche/d4e6efedfa1e4e91ab65 in order to visualize the legend.
here's my result :
But, i need something similar to this :
so my question now, is how can i have a customized legend
You may use a plt.table as a legend.
import matplotlib.pyplot as plt
import numpy as np
valeur = np.array([.1,.45,.7])
text=[["Faible","Ng<1,5" ],["Moyenne","1,5<Ng<2,5"],[u"Elevée", "Ng>2,5"]]
colLabels = ["Exposition", u"Densité"]
tab=plt.table(cellText=text, colLabels=colLabels,
colWidths = [0.2,0.2], loc='lower right',
cellColours=plt.cm.hot_r(np.c_[valeur,valeur]))
plt.show()
In order to link this table to a contourf plot, you may do as follows:
from matplotlib import pyplot as plt
import numpy as np
a = np.sort(np.random.rand(100)).reshape(10,10)*4
levels = np.array([0,1.5,2.5,4])
sm = plt.contourf(a, levels = levels, cmap=plt.cm.hot_r )
text=[["Faible","Ng<1,5" ],["Moyenne","1,5<Ng<2,5"],[u"Elevée", "Ng>2,5"]]
colLabels = ["Exposition", u"Densité"]
col = levels[:-1] + np.diff(levels)/2.
cellcol = sm.cmap(sm.norm(np.c_[col,col]))
tax = plt.gcf().add_axes([0,0,1,1])
tab=tax.table(cellText=text, colLabels=colLabels,
colWidths = [0.2,0.2], loc='lower left',
cellColours=cellcol )
tax.axis("off")
plt.show()

PyPlot not showing on Windows

So I have my backend set to atkgg but pyplot still doesn't show the graph window. Code:
from matplotlib import pyplot as plt
def ex1():
plt.figure(1)
plt.plot([1,1],[2,2],[3,3],[4,4], 'ro')
plt.draw()
plt.show()

Embed a pyplot in a tkinter window and update it

I am trying to write a program that has a pyplot (as in matplotlib.pyplot) within a Tkinter GUI which can be updated. Basically what I want is a program with a Tkinter interface to be displaying some data on a pyplot, then when the program gets some new data I want to update the pyplot to contain the new data.
Here is a minimal example:
import numpy as np
import Tkinter as tk
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
root = tk.Tk()
fig = plt.figure(1)
t = np.arange(0.0,3.0,0.01)
s = np.sin(np.pi*t)
plt.plot(t,s)
canvas = FigureCanvasTkAgg(fig, master=root)
plot_widget = canvas.get_tk_widget()
def update():
s = np.cos(np.pi*t)
plt.plot(t,s)
plt.draw()
plot_widget.grid(row=0, column=0)
tk.Button(root,text="Update",command=update).grid(row=1, column=0)
root.mainloop()
What I expect to happen is, for a window to pop up with a plot containing a sine wave and a button. When I press the button a cosine wave should appear on the plot.
What actually happens when I run the program is that a window pops up with a plot containing a sine wave and a button. However when I press the button nothing happens. The plot does not seem to be updating.
I'm probably making some newbie mistake but I can't find any examples online of doing this sort of thing. What is going wrong here and how would I get what I want?
Any help would be greatly appreciated!
I figured it out, I need to call the draw() method on the figure's canvas attribute in order to get it to redraw, the corrected code is below. Also anyone who is encountering this or similar problems should probably look at matplotlib.animate if they need to be dynamically updating their pyplot
import numpy as np
import Tkinter as tk
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
root = tk.Tk()
fig = plt.figure(1)
plt.ion()
t = np.arange(0.0,3.0,0.01)
s = np.sin(np.pi*t)
plt.plot(t,s)
canvas = FigureCanvasTkAgg(fig, master=root)
plot_widget = canvas.get_tk_widget()
def update():
s = np.cos(np.pi*t)
plt.plot(t,s)
#d[0].set_ydata(s)
fig.canvas.draw()
plot_widget.grid(row=0, column=0)
tk.Button(root,text="Update",command=update).grid(row=1, column=0)
root.mainloop()