Why isn't my line graph showing up on GUI - python

This is a function which is being called on a button click. It is supposed to display a line graph why is it not showing up.
def plotk2(self):
#----------------------------------------------------------------Data
temp=full_dataset[['country_txt','iyear','nkill']]
text = self.k_count.currentText()
temp = temp[temp['country_txt'].str.match(text)]
temp2=temp.groupby(['iyear'])['nkill'].count()
temp2=temp2.to_frame()
temp2['iyear']=temp2.index
#----------------------------------------------------------------
self.figure.clear()
ax = self.figure.add_subplot(111)
plt.plot( 'nkill', 'iyear', data=temp2)
#ax.axis('off')
plt.show()
self.canvas.draw()

If you want to draw on PyQt you must use FigureCanvas, not matplotlib.pyplot, so if you use plt.plot() you will not draw anything.
In your case a similar example would be:
import sys
import pandas as pd
import matplotlib
matplotlib.use('Qt5Agg')
from PyQt5 import QtCore, QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
class Widget(QtWidgets.QWidget):
def __init__(self, *args, **kwargs):
QtWidgets.QWidget.__init__(self, *args, **kwargs)
self.figure = Figure(figsize=(5, 4), dpi=100)
self.canvas = FigureCanvas(self.figure)
self.canvas.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
button = QtWidgets.QPushButton("random plot")
button.clicked.connect(self.plot)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.canvas)
lay.addWidget(button)
self.plot()
def plot(self):
self.figure.clear()
ax = self.figure.add_subplot(111)
d = {'nkill': [1, 2, 4, 5, 6], 'iyear': [3, 4, 5, 5, 5]}
df = pd.DataFrame(data=d)
ax.plot('nkill', 'iyear', data=df)
# ax.axis('off')
self.canvas.draw()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())

Related

How to make matplotlib widget in PyQt5 clickable?

I am working on GUI where I have tab system with graphs. I want that if a user clicks (or puts cursor) at any point in the graph, it shows the exact x and y values in that point like that:
I know that in usual matplotlib it is easy to implement; however I do not know how to do that in PyQt5.
My tabs system and canvas look like that:
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from PyQt5.QtWidgets import QDialog
from PyQt5.QtWidgets import QApplication, QWidget,QVBoxLayout,QTabWidget
import sys
import matplotlib.pyplot as plt
def mouse_move(event):
x, y = event.xdata, event.ydata
print(x, y)
plt.connect('motion_notify_event', mouse_move)
class Canvas(FigureCanvas):
def __init__(self, parent=None, width=5, height=5, dpi=80):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
FigureCanvas.__init__(self, fig)
self.setParent(parent)
self.plot()
def plot(self):
x = ['22-02 11:16:15', '22-02 15:31:54', '22-02 15:32:30',
'22-02 15:32:45', '22-02 15:33:57', '22-02 15:34:13',
'22-02 15:34:46']
y = [1, 4, 3, 4, 8, 9, 2]
self.figure.tight_layout()
ax = self.figure.add_subplot(111)
ax.plot(x, y)
class MainWindow(QDialog):
def __init__(self):
super().__init__()
self.top = 255
self.left = 150
self.setGeometry(self.left, self.top, 900, 900)
self.Mainlayout = QVBoxLayout(self)
self.tabs = QTabWidget()
self.graphUP = QWidget()
self.graphUP.layout = QVBoxLayout( self.graphUP)
self.graphUP.layout.addWidget(Canvas())
self.tabs.setFixedHeight(800)
self.tabs.setFixedWidth(800)
self.tabs.addTab(self.graphUP, "Graph1")
self.Mainlayout.addWidget(self.tabs)
self.show()
if __name__ == '__main__':
App = QApplication(sys.argv)
window = MainWindow()
sys.exit(App.exec())
import this module:
import mplcursors as mpl
and add : mpl.cursor(hover=True)
in your def plot() function.

Embedding second animated graph to PyQt5 GUI

I want to add a second animated graph to the GUI holding my first animated graph with both graphs animating at the same time, but I'm not sure how.
Here is my code :
import sys
import numpy as np
from matplotlib.backends.qt_compat import QtWidgets
from matplotlib.backends.backend_qt5agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
from matplotlib import animation
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
layout = QtWidgets.QVBoxLayout(self._main)
self.fig = Figure(figsize=(5, 3))
self.canvas = FigureCanvas(self.fig)
layout.addWidget(self.canvas)
self.addToolBar(NavigationToolbar(self.canvas, self))
self.setup()
def setup(self):
self.ax = self.fig.subplots()
self.ax.set_aspect('equal')
self.ax.grid(True, linestyle = '-', color = '0.10')
self.ax.set_xlim([-15, 15])
self.ax.set_ylim([-15, 15])
self.scat = self.ax.scatter([], [], c=(0.9, 0.1, 0.5), zorder=3)
self.scat.set_alpha(0.8)
self.anim = animation.FuncAnimation(self.fig, self.update,
frames = 720, interval = 10)
def update(self, i):
self.scat.set_offsets(([np.cos(np.radians(i))*7.5, np.sin(np.radians(i))*7.5], [0,0]))
if __name__ == "__main__":
qapp = QtWidgets.QApplication(sys.argv)
app = ApplicationWindow()
app.show()
qapp.exec_()
And here is some sample code which has two graphs inside the same window (like how I want to)
Here they use an _update_canvas function for the animated graph and the other graph (which is just a static graph) they plot it in the application window class.
I'm using an update plot function to animate my graph, do I need a second update plot function? How?
Sample code:
import sys
import time
import numpy as np
from matplotlib.backends.qt_compat import QtCore, QtWidgets, is_pyqt5
if is_pyqt5():
from matplotlib.backends.backend_qt5agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
else:
from matplotlib.backends.backend_qt4agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
layout = QtWidgets.QVBoxLayout(self._main)
static_canvas = FigureCanvas(Figure(figsize=(5, 3)))
layout.addWidget(static_canvas)
self.addToolBar(NavigationToolbar(static_canvas, self))
dynamic_canvas = FigureCanvas(Figure(figsize=(5, 3)))
layout.addWidget(dynamic_canvas)
self.addToolBar(QtCore.Qt.BottomToolBarArea,
NavigationToolbar(dynamic_canvas, self))
self._static_ax = static_canvas.figure.subplots()
t = np.linspace(0, 10, 501)
self._static_ax.plot(t, np.tan(t), ".")
self._dynamic_ax = dynamic_canvas.figure.subplots()
self._timer = dynamic_canvas.new_timer(
100, [(self._update_canvas, (), {})])
self._timer.start()
def _update_canvas(self):
self._dynamic_ax.clear()
t = np.linspace(0, 10, 101)
# Shift the sinusoid as a function of time.
self._dynamic_ax.plot(t, np.sin(t + time.time()))
self._dynamic_ax.figure.canvas.draw()
if __name__ == "__main__":
qapp = QtWidgets.QApplication(sys.argv)
app = ApplicationWindow()
app.show()
qapp.exec_()
To embed multiple animated graphs, you need to create multiple plot objects(Figure and FigureCanvas) then add each object to the QVBoxLayout. If you wanted to display it horizontally, you can use a QHBoxLayout. Each plot object will have its own subplot, grid, and data. To update each plot's data, you will need each plot to have its individual plot update function where you can pass this to the animation.FuncAnimation handler. So in your case, to have two animated graphs, you will need two update plot functions.
from matplotlib.figure import Figure
from matplotlib import animation
import numpy as np
import sys, matplotlib
from PyQt5 import QtWidgets, QtCore
from matplotlib.backends.backend_qt5agg import (FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
layout = QtWidgets.QVBoxLayout(self._main)
# Configure figure 1
self.fig1 = Figure(figsize=(5, 3))
self.canvas1 = FigureCanvas(self.fig1)
# Configure figure 2
self.fig2 = Figure(figsize=(5, 3))
self.canvas2 = FigureCanvas(self.fig2)
layout.addWidget(self.canvas1)
layout.addWidget(self.canvas2)
self.addToolBar(NavigationToolbar(self.canvas1, self))
self.addToolBar(QtCore.Qt.BottomToolBarArea, NavigationToolbar(self.canvas2, self))
self.setup()
def setup(self):
# Plot 1 (top)
self.ax1 = self.fig1.subplots()
self.ax1.set_aspect('equal')
self.ax1.grid(True, linestyle = '-', color = '0.10')
self.ax1.set_xlim([-15, 15])
self.ax1.set_ylim([-15, 15])
# Plot 2 (bottom)
self.ax2 = self.fig2.subplots()
self.ax2.set_aspect('equal')
self.ax2.grid(True, linestyle = '-', color = '0.10')
self.ax2.set_xlim([-15, 15])
self.ax2.set_ylim([-15, 15])
self.scat1 = self.ax1.scatter([], [], c=(0.9, 0.1, 0.5), zorder=3)
self.scat1.set_alpha(0.8)
self.scat2 = self.ax2.scatter([], [], c=(0.9, 0.1, 0.5), zorder=3)
self.scat2.set_alpha(0.8)
self.anim1 = animation.FuncAnimation(self.fig1, self.update1,frames = 720, interval = 10)
self.anim2 = animation.FuncAnimation(self.fig2, self.update2,frames = 720, interval = 10)
# Update data for plot 1
def update1(self, i):
self.scat1.set_offsets(([np.cos(np.radians(i))*7.5, np.sin(np.radians(i))*7.5], [0,0]))
# Update data for plot 2
def update2(self, i):
self.scat2.set_offsets(([np.cos(np.radians(i))*7.5, np.sin(np.radians(i))*7.5], [0,0]))
if __name__ == "__main__":
qapp = QtWidgets.QApplication(sys.argv)
app = ApplicationWindow()
app.show()
qapp.exec_()
Is there a specific reason you need two separate canvas and two separate figures? If not, then I agree with ImportanceOfBeingErnest's comment and that you should create only one figure/canvas with 2 subplots, and call a single update function that takes care of updating the content of both axes.
In essence, your question would be a duplicate of this one, except for the fact that you are embedding the animation in a Qt app.
import sys
import time
import numpy as np
from matplotlib.backends.qt_compat import QtCore, QtWidgets, is_pyqt5
if is_pyqt5():
from matplotlib.backends.backend_qt5agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
else:
from matplotlib.backends.backend_qt4agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
layout = QtWidgets.QVBoxLayout(self._main)
self.fig = Figure(figsize=(5, 6))
self.canvas = FigureCanvas(self.fig)
layout.addWidget(self.canvas)
self.addToolBar(QtCore.Qt.BottomToolBarArea,
NavigationToolbar(self.canvas, self))
self._axs = self.fig.subplots(2, 1)
self._timer = self.canvas.new_timer(
100, [(self._update_canvas, (), {})])
self._timer.start()
def _update_canvas(self):
[ax.clear() for ax in self._axs]
t = np.linspace(0, 10, 501)
self._axs[0].plot(t, np.tan(t + time.time()), ".")
t = np.linspace(0, 10, 101)
self._axs[1].plot(t, np.sin(t + time.time()))
self.canvas.draw()
if __name__ == "__main__":
qapp = QtWidgets.QApplication(sys.argv)
app = ApplicationWindow()
app.show()
qapp.exec_()

Matplotlib pie chart - How to center label?

I added rotated labels to my pie chart and expected that by default labels would be centered in each slice of the pie chart. But this is not the case
How can I center my labels?
Here my backend code:
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget
from frontend import Ui_MainWindow
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt
class Ui_MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(Ui_MainWindow, self).__init__(parent)
self.setupUi(self)
self.graph = MyCanvas()
self.gridLayout.addWidget(self.graph, 0, 0, 1, 1)
self.graph.figure.clf()
self.axes = self.graph.figure.add_subplot(111)
self.y = [1,2,3, 4,8,16,32]
self.label = ['1.52%', '3.03%', '4.55%', '6.06%', '12.12%', '24.24%', '48.48%']
self.axes.pie(self.y, labels=self.label, labeldistance=0.6, rotatelabels =True)
class MyCanvas(FigureCanvas):
def __init__(self, *args, **kwargs):
self.figure = plt.figure()
FigureCanvas.__init__(self, self.figure)
self.figure.patch.set_facecolor("None")
self.figure.subplots_adjust(left=0.08, bottom=0.10, right=0.99, top=0.97)
if __name__ == '__main__':
app = QApplication(sys.argv)
prog = Ui_MainWindow()
prog.show()
sys.exit(app.exec_())
Looking at the documentation, you can pass dedicated options to the text objects in your pie chart using the textprops keyword. textprops accepts a dict, which apparently accepts all options that are accepted by matplotlib.text.Text. Feeding it the options rotation_mode='anchor', va='center' and ha='left' gives pretty good results:
import matplotlib.pyplot as plt
figure = plt.figure()
figure.patch.set_facecolor("None")
figure.subplots_adjust(left=0.08, bottom=0.10, right=0.99, top=0.97)
figure.clf()
axes = figure.add_subplot(111)
axes.set_aspect(1)
y = [1,2,3, 4,8,16,32]
label = ['1.52%', '3.03%', '4.55%', '6.06%', '12.12%', '24.24%', '48.48%']
axes.pie(
y, labels=label, labeldistance=0.6, rotatelabels =True,
textprops = dict(rotation_mode = 'anchor', va='center', ha='left'),
)
plt.show()
The result of the code looks like this:
Note that I added ax.set_aspect(1) to make the pie chart circular. If you don't want that, just leave out that line.

Rotate or resize the axis ticks using pyqt5 in python

I use the following code
import sys
from PyQt5.QtWidgets import QDialog, QApplication, QPushButton, QVBoxLayout, \
QLineEdit, QMessageBox, QInputDialog, QLabel, QHBoxLayout, QGridLayout, QStackedLayout, QFormLayout
from PyQt5 import QtCore, QtGui, QtWidgets
import time
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.lines import Line2D
import matplotlib.animation as animation
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
# data
import numpy as np
#import matplotlib.pyplot as plt
import pandas as pd
import os
import csv
# percent MW
x=['BE2000',
'BE2020',
'BE5000',
'BE6010',
'BE6017',
'BE6020',
'BE6027',
'BE6030',
'BE6050',
'BE6057',
'BE6061',
'BE6062',
'BE6063',
'BE6070',
'BE6073',
'BE6075',
'BE6080',
'BE6090',
'BE7000',
'BE7010']
y=[0.0002716766988612973,
0.005178087393490427,
0.0014053668695097226,
0.3174139251746979,
0.006049724003653125,
0.24824287385322272,
0.0004986331396716525,
0.19624266416568525,
0.13170894569069627,
0.0028535946936992873,
0.0002737864422892905,
0.0011817396106664916,
0.0029533382584451574,
0.03281361420815501,
0.000273411124091493,
0.002558801432193384,
0.027004861403488886,
0.004918720459633545,
0.006030278629435105,
0.0002858345295419518]
#figure = plt.figure()
H = np.array([[100, 2, 39, 190], [402, 55, 369, 1023], [300, 700, 8, 412], [170, 530, 330, 1]])
Z = np.array([[3, 290, 600, 480], [1011, 230, 830, 0], [152, 750, 5, 919], [340, 7, 543, 812]])
class Window(QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
# a figure instance to plot on
self.figure = plt.figure()
# this is the Canvas Widget that displays the `figure`
# it takes the `figure` instance as a parameter to __init_
self.im = None
self.canvas = FigureCanvas(self.figure)
self.canvas.mpl_connect('button_press_event', self.on_button_press_event)
# this is the Navigation widget
# it takes the Canvas widget and a parent
self.toolbar = NavigationToolbar(self.canvas, self)
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self.plot)
self.timer.setInterval(500)
# Just some button connected to `plot` method
self.button = QPushButton('Plot')
self.button.clicked.connect(self.timer.start)
self.button.setDefault(False)
self.stop = QPushButton("Stop")
self.stop.clicked.connect(self.timer.stop)
self.stop.setDefault(False)
self.exit = QPushButton('Exit')
self.exit.clicked.connect(self.close)
self.exit.setDefault(True)
# set the layout
layout = QFormLayout()
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
layout.addWidget(self.button)
layout.addWidget(self.stop)
layout.addWidget(self.exit)
self.setLayout(layout)
self.lb = QtWidgets.QLabel(self)
self.lb.setWindowFlags(QtCore.Qt.ToolTip)
def plot(self):
data=x
self.setWindowTitle("Bestandseingruppierung")
# instead of ax.hold(False)
self.figure.clear()
# create an axis
ax = self.figure.add_subplot(111)
plt.setp(ax.get_xticklabels(), rotation=45)
#fig.autofmt_xdate()
# discards the old graph
ax.hold(False) # deprecated, see above
# plot data
ax.axes.bar(data,y)
self.canvas.draw()
def on_button_press_event(self, event):
print('button={}, x={}, y={}, xdata={}, ydata={}'
.format(event.button, event.x, event.y, event.xdata, event.ydata))
if self.im:
message = str(self.im.get_cursor_data(event))
delay = 1000
w = self.lb.fontMetrics().width(message)
self.lb.resize(w, self.lb.size().height())
self.lb.setText(message)
self.lb.move(QtGui.QCursor.pos())
self.lb.show()
QtCore.QTimer.singleShot(delay, self.lb.hide)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Window()
main.show()
sys.exit(app.exec_())
to generate a dynamical bar chart. Now there is a problem in the the plot.
.
I tried ax.set_xticklabels to rotate the ticks on the x-axis in two different positions:
1) directly after creating the figure:
class Window(QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
# a figure instance to plot on
self.figure = plt.figure()
self.figure.set_xticklabels(rotation=45)
which produces an error.
2) as the second attempt I placed it in
def plot(self):
data=x
self.setWindowTitle("Bestandseingruppierung")
# instead of ax.hold(False)
self.figure.clear()
# create an axis
ax = self.figure.add_subplot(111)
ax.set_xticklabels(rotation=45)
#fig.autofmt_xdate()
# discards the old graph
ax.hold(False) # deprecated, see above
# plot data
ax.axes.bar(data,y)
self.canvas.draw()
In this case I get the old plot without any error but any rotation!
I would like to know which options and where should I place to get either an rotation of the ticks or to resize the ticks or labels by using pyqt5!
Your second attempt was quite close to right way!
Just add your x-labels to ax.set_xticklabels(rotation=45) as a first positional parameter.
So, copy this line of code and place it into your second attempt:
ax.set_xticklabels(labels=xlabels, rotation=45)
where xlabels = list of your x-axis labels

Using PyQt5 to embed a dynamical bar chart

I wrote the following code in python to show a bar chart in the GUI generated by PyQt5.
import sys
from PyQt5.QtWidgets import QDialog, QApplication, QPushButton, QVBoxLayout, \
QLineEdit, QMessageBox, QInputDialog, QLabel, QHBoxLayout, QGridLayout, QStackedLayout, QFormLayout
from PyQt5 import QtCore, QtGui, QtWidgets
import time
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.lines import Line2D
import matplotlib.animation as animation
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt
# data
import numpy as np
#import matplotlib.pyplot as plt
import pandas as pd
import os
import csv
#define the path to data
pathToData='C:/RC/python/data/'
dataName= '31122017ARB.csv'
# import
data=pd.read_csv(pathToData+dataName, delimiter=';',encoding='cp1252')
# percent MW
data['MWP']=data[' MW ']/sum(data[' MW '])
#aggregate by Best
datag=data.groupby('Best', as_index=False).agg({'MW': 'sum'})
x=["BE"+s for s in[str(s) for s in [int(x) for x in datag.iloc[:,0].tolist()]]]
y=datag.ix[:,1].tolist()
figure = plt.figure()
H = np.array([[100, 2, 39, 190], [402, 55, 369, 1023], [300, 700, 8, 412], [170, 530, 330, 1]])
Z = np.array([[3, 290, 600, 480], [1011, 230, 830, 0], [152, 750, 5, 919], [340, 7, 543, 812]])
class Window(QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
# a figure instance to plot on
self.figure = plt.figure()
# this is the Canvas Widget that displays the `figure`
# it takes the `figure` instance as a parameter to __init_
self.im = None
self.canvas = FigureCanvas(self.figure)
self.canvas.mpl_connect('button_press_event', self.on_button_press_event)
# this is the Navigation widget
# it takes the Canvas widget and a parent
self.toolbar = NavigationToolbar(self.canvas, self)
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self.plot)
self.timer.setInterval(5000)
# Just some button connected to `plot` method
self.button = QPushButton('Plot')
self.button.clicked.connect(self.timer.start)
self.button.setDefault(False)
self.stop = QPushButton("Stop")
self.stop.clicked.connect(self.timer.stop)
self.stop.setDefault(False)
self.exit = QPushButton('Exit')
self.exit.clicked.connect(self.close)
self.exit.setDefault(True)
layout = QFormLayout()
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
layout.addWidget(self.button)
layout.addWidget(self.stop)
layout.addWidget(self.exit)
self.setLayout(layout)
self.lb = QtWidgets.QLabel(self)
self.lb.setWindowFlags(QtCore.Qt.ToolTip)
def plot(self):
self.x = ["BE"+s for s in[str(s) for s in [int(x) for x in datag.iloc[:,0].tolist()]]]
self.y = datag.iloc[:,1].tolist()#np.sin(self.x)
self.setWindowTitle("Bestandseingruppierung")
def update_figure(self):
self.axes.bar(self.x, self.y)
#self.y = np.roll(self.y,-1)
#self.draw()
self.canvas.draw()
def on_button_press_event(self, event):
print('button={}, x={}, y={}, xdata={}, ydata={}'
.format(event.button, event.x, event.y, event.xdata, event.ydata))
if self.im:
message = str(self.im.get_cursor_data(event))
delay = 1000
w = self.lb.fontMetrics().width(message)
self.lb.resize(w, self.lb.size().height())
self.lb.setText(message)
self.lb.move(QtGui.QCursor.pos())
self.lb.show()
QtCore.QTimer.singleShot(delay, self.lb.hide)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Window()
main.show()
sys.exit(app.exec_())
The Problem is: it is not shown any plot, even I do not get any error. I just obtain an empty .
How can I get the chart by pressing the plot bottom? I guess, I am doing some thing wrong under def plot(self):.
Just because of clarification: I tested the chart within a GUI generated by PyQt5 as a stand alone code, which works totally fine:
# FigureCanvas inherits QWidget
class MainWindow(FigureCanvas):
def __init__(self, parent=None, width=4, height=3, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
self.axes.hold(False)
super(MainWindow, self).__init__(fig)
self.setParent(parent)
FigureCanvas.setSizePolicy(self,
QSizePolicy.Expanding,
QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)
timer = QTimer(self)
timer.timeout.connect(self.update_figure)
timer.start(50)
self.x = ["BE"+s for s in[str(s) for s in [int(x) for x in datag.iloc[:,0].tolist()]]]#np.arange(0, 4*np.pi, 0.1)
self.y = datag.iloc[:,1].tolist()#np.sin(self.x)
self.setWindowTitle("Best")
def update_figure(self):
self.axes.bar(self.x, self.y)
#self.y = np.roll(self.y,-1)
self.draw()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
I found the solution!
I have 3 botons in this GUI as shown in the following part of the code:
class Window(QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
# a figure instance to plot on
self.figure = plt.figure()
# this is the Canvas Widget that displays the `figure`
# it takes the `figure` instance as a parameter to __init_
self.im = None
self.canvas = FigureCanvas(self.figure)
self.canvas.mpl_connect('button_press_event', self.on_button_press_event)
# this is the Navigation widget
# it takes the Canvas widget and a parent
self.toolbar = NavigationToolbar(self.canvas, self)
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self.plot)
self.timer.setInterval(0)
# Just some button connected to `plot` method
self.button = QPushButton('Plot')
self.button.clicked.connect(self.timer.start)
self.button.setDefault(False)
self.stop = QPushButton("Stop")
self.stop.clicked.connect(self.timer.stop)
self.stop.setDefault(False)
self.exit = QPushButton('Exit')
self.exit.clicked.connect(self.close)
self.exit.setDefault(True)
One has to set the time delay in self.timer.setInterval(0) to Zero! That is the first point.
The part def plot(self) should be changed as follows:
def plot(self):
data=x
self.setWindowTitle("Bestandseingruppierung")
# instead of ax.hold(False)
self.figure.clear()
# create an axis
ax = self.figure.add_subplot(111)
#fig.autofmt_xdate()
# discards the old graph
ax.hold(False) # deprecated, see above
# plot data
ax.axes.bar(data,y)
self.canvas.draw()

Categories

Resources