I'm trying to use interactive plotting capabilities of matplotlib embeded into pyqt5 window with mpl version : 2.1.1
I provided minimal example with UI file here:
https://ufile.io/8irs7
and python code:
import matplotlib
matplotlib.use("Qt5Agg")
import sys
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import pandas as pd
import numpy as np
from PyQt5 import QtWidgets, uic # works for pyqt5
from PyQt5.Qt import QVBoxLayout
# import numpy as np
qtCreatorFile = "window.ui" # Enter file here.
# qtCreatorFile = "pssga.ui"
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
class PlotSeries(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
#create figure
self.fig=Figure()
self.axes = self.fig.add_subplot(111)
self.axes.grid()
self.canvas=FigureCanvas(self.fig)
#add plot toolbar from matplotlib
self.toolbar = NavigationToolbar(self.canvas, self)
#create new layout
layout = QVBoxLayout()
layout.addWidget(self.canvas)
layout.addWidget(self.toolbar)
#add layout to qwidget
self.plotlayout=self.widgetplot.setLayout(layout)
#draw the canvas !
self.canvas.draw()
#now let's call widget
self.plot_basegraph()
def plot_basegraph(self):
#create simple time series
for i in range(0,5):
ts=pd.Series(np.random.randn(2000), index=pd.date_range('1/1/2015',freq='h', periods=2000),name="series "+str(i))
if i==0:
self.stackTSPD=ts.to_frame()
else:
self.stackTSPD=self.stackTSPD.join(ts.to_frame(),how='inner')
print(matplotlib.__version__)
self.axes.clear()
self.axes.grid()
for i in self.stackTSPD.columns.values:
t=self.stackTSPD.index.to_pydatetime()
y=self.stackTSPD[i].values
self.axes.plot(t,y, label=i)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = PlotSeries()
window.show()
sys.exit(app.exec_())
Zooming into time series, panning works as expected but when I try to press "Home" - reset original view it crashes:
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_qt5agg.py", line 155, in __draw_idle_agg
self.draw()
File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_qt5agg.py", line 127, in draw
super(FigureCanvasQTAggBase, self).draw()
File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_agg.py", line 430, in draw
self.figure.draw(self.renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/figure.py", line 1299, in draw
renderer, self, artists, self.suppressComposite)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/image.py", line 138, in _draw_list_compositing_images
a.draw(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/axes/_base.py", line 2437, in draw
mimage._draw_list_compositing_images(renderer, self, artists)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/image.py", line 138, in _draw_list_compositing_images
a.draw(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/axis.py", line 1133, in draw
ticks_to_draw = self._update_ticks(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/axis.py", line 974, in _update_ticks
tick_tups = list(self.iter_ticks())
File "/usr/local/lib/python3.5/dist-packages/matplotlib/axis.py", line 917, in iter_ticks
majorLocs = self.major.locator()
File "/usr/local/lib/python3.5/dist-packages/matplotlib/dates.py", line 1061, in __call__
self.refresh()
File "/usr/local/lib/python3.5/dist-packages/matplotlib/dates.py", line 1081, in refresh
dmin, dmax = self.viewlim_to_dt()
File "/usr/local/lib/python3.5/dist-packages/matplotlib/dates.py", line 839, in viewlim_to_dt
return num2date(vmin, self.tz), num2date(vmax, self.tz)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/dates.py", line 445, in num2date
return _from_ordinalf(x, tz)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/dates.py", line 260, in _from_ordinalf
dt = datetime.datetime.fromordinal(ix).replace(tzinfo=UTC)
ValueError: ordinal must be >= 1
This behavior started when I tried to embed this time series plot into pyqt5 form. When plot opened separately in a new GTK window it worked without any problem. I've attached example with working home button which opens in na non pyqt window...
'''
Created on 16. jan. 2018
@author: gregor
'''
import matplotlib as mpl
import matplotlib.pyplot as plt
# matplotlib.use("Qt5Agg")
# from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
# from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
# from matplotlib.figure import Figure
import pandas as pd
import numpy as np
class PlotSeries():
def __init__(self):
self.fig,self.axes = plt.subplots()
self.axes.grid()
# self.canvas=FigureCanvas(self.fig)
#add plot toolbar from matplotlib
# self.toolbar = NavigationToolbar(self.canvas, self)
#create new layout
# layout = QVBoxLayout()
#
# layout.addWidget(self.canvas)
# layout.addWidget(self.toolbar)
#
# #add layout to qwidget
# self.plotlayout=self.widgetplot.setLayout(layout)
#
# #draw the canvas !
# self.canvas.draw()
#now let's call widget
self.plot_basegraph()
def plot_basegraph(self):
#create simple time series
for i in range(0,5):
ts=pd.Series(np.random.randn(2000), index=pd.date_range('1/1/2015',freq='h', periods=2000),name="series "+str(i))
if i==0:
self.stackTSPD=ts.to_frame()
else:
self.stackTSPD=self.stackTSPD.join(ts.to_frame(),how='inner')
print(mpl.__version__)
self.axes.clear()
self.axes.grid()
for i in self.stackTSPD.columns.values:
t=self.stackTSPD.index.to_pydatetime()
y=self.stackTSPD[i].values
self.axes.plot_date(t,y, label=i)
plt.show()
if __name__ == "__main__":
PlotSeries()
Thank you !