numpy matplotlib show()不会工作两次

bksxznpy  于 2024-01-08  发布在  其他
关注(0)|答案(6)|浏览(114)

我有一个奇怪的问题,matplotlib。如果我运行这个程序,我可以打开和关闭几次相同的数字。

  1. import numpy
  2. from pylab import figure, show
  3. X = numpy.random.rand(100, 1000)
  4. xs = numpy.mean(X, axis=1)
  5. ys = numpy.std(X, axis=1)
  6. fig = figure()
  7. ax = fig.add_subplot(111)
  8. ax.set_title('click on point to plot time series')
  9. line, = ax.plot(xs, ys, 'o', picker=5) # 5 points tolerance
  10. def onpick(event):
  11. figi = figure()
  12. ax = figi.add_subplot(111)
  13. ax.plot([1,2,3,4])
  14. figi.show()
  15. fig.canvas.mpl_connect('pick_event', onpick)
  16. show()

字符串
相反,如果我在我的自定义小部件中使用相同的onpick函数代码,它只会在第一次打开图形,在其他事件中,它会进入函数,但不会显示图形:

  1. from PyQt4 import QtGui, QtCore
  2. from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
  3. from matplotlib.figure import Figure
  4. import numpy as np
  5. import matplotlib.pyplot as plt
  6. from matplotlib.backends.backend_qt4 import NavigationToolbar2QT as NavigationToolbar
  7. import time
  8. STEP = 0.000152
  9. class MplCanvas(FigureCanvas):
  10. def __init__(self):
  11. # initialization of the canvas
  12. FigureCanvas.__init__(self, Figure())
  13. self.queue = []
  14. self.I_data = np.array([])
  15. self.T_data = np.array([])
  16. self.LvsT = self.figure.add_subplot(111)
  17. self.LvsT.set_xlabel('Time, s')
  18. self.LvsT.set_ylabel('PMT Voltage, V')
  19. self.LvsT.set_title("Light vs Time")
  20. self.LvsT.grid(True)
  21. self.old_size = self.LvsT.bbox.width, self.LvsT.bbox.height
  22. self.LvsT_background = self.copy_from_bbox(self.LvsT.bbox)
  23. self.LvsT_plot, = self.LvsT.plot(self.T_data,self.I_data)
  24. #self.LvsT_plot2, = self.LvsT.plot(self.T_data2,self.I_data2)
  25. self.mpl_connect('axes_enter_event', self.enter_axes)
  26. self.mpl_connect('button_press_event', self.onpick)
  27. self.count = 0
  28. self.draw()
  29. def enter_axes(self,event):
  30. print "dentro"
  31. def onpick(self,event):
  32. print "click"
  33. print 'you pressed', event.canvas
  34. a = np.arange(10)
  35. print a
  36. print self.count
  37. fig = plt.figure()
  38. ax = fig.add_subplot(111)
  39. ax.plot(a)
  40. fig.show()
  41. def Start_Plot(self,q,Vmin,Vmax,ScanRate,Cycles):
  42. self.queue = q
  43. self.LvsT.clear()
  44. self.LvsT.set_xlim(0,abs(Vmin-Vmax)/ScanRate*Cycles)
  45. self.LvsT.set_ylim(-3, 3)
  46. self.LvsT.set_autoscale_on(False)
  47. self.LvsT.clear()
  48. self.draw()
  49. self.T_data = np.array([])
  50. self.I_data = np.array([])
  51. # call the update method (to speed-up visualization)
  52. self.timerEvent(None)
  53. # start timer, trigger event every 1000 millisecs (=1sec)
  54. self.timerLvsT = self.startTimer(3)
  55. def timerEvent(self, evt):
  56. current_size = self.LvsT.bbox.width, self.LvsT.bbox.height
  57. if self.old_size != current_size:
  58. self.old_size = current_size
  59. self.LvsT.clear()
  60. self.LvsT.grid()
  61. self.draw()
  62. self.LvsT_background = self.copy_from_bbox(self.LvsT.bbox)
  63. self.restore_region(self.LvsT_background, bbox=self.LvsT.bbox)
  64. result = self.queue.get()
  65. if result == 'STOP':
  66. self.LvsT.draw_artist(self.LvsT_plot)
  67. self.killTimer(self.timerLvsT)
  68. print "Plot finito LvsT"
  69. else:
  70. # append new data to the datasets
  71. self.T_data = np.append(self.T_data,result[0:len(result)/2])
  72. self.I_data = np.append(self.I_data,result[len(result)/2:len(result)])
  73. self.LvsT_plot.set_data(self.T_data,self.I_data)#L_data
  74. #self.LvsT_plot2.set_data(self.T_data2,self.I_data2)#L_data
  75. self.LvsT.draw_artist(self.LvsT_plot)
  76. self.blit(self.LvsT.bbox)
  77. class LvsT_MplWidget(QtGui.QWidget):
  78. def __init__(self, parent = None):
  79. QtGui.QWidget.__init__(self, parent)
  80. self.canvas = MplCanvas()
  81. self.vbl = QtGui.QVBoxLayout()
  82. self.vbl.addWidget(self.canvas)
  83. self.setLayout(self.vbl)


这个小部件是动画绘图所需的,当实验完成时,如果我点击绘图,它应该会出现一个图形,只会在第一次出现。
你有什么线索吗?
非常感谢

rxztt3cl

rxztt3cl1#

在代码的开头,通过plt.ion()启用交互模式。

ujv3wf0j

ujv3wf0j2#

我有新的信息,这是一个谷歌搜索出现
这是matplotlib的作者写的,来自http://old.nabble.com/calling-show%28%29-twice-in-a-row-td24276907.html
你好Ondrej,
我不知道在哪里可以找到一个很好的解释,但让我给你给予一些提示。它旨在每个程序只使用一次show。也就是说,“show”应该是你脚本中的最后一行。如果你想要交互式绘图,你可以考虑交互式模式(pyplot.ion-ioff),如下面的例子。
此外,对于动态绘图,所有动画演示可能都很有用。
你也可以看看http://matplotlib.sourceforge.net/users/shell.html
最好的问候马蒂亚斯
因此,它似乎是一个未记录的“功能”(bug?)。
Edit:这里是他的代码块:

  1. from pylab import *
  2. t = linspace(0.0, pi, 100)
  3. x = cos(t)
  4. y = sin(t)
  5. ion() # turn on interactive mode
  6. figure(0)
  7. subplot(111, autoscale_on=False, xlim=(-1.2, 1.2), ylim=(-.2, 1.2))
  8. point = plot([x[0]], [y[0]], marker='o', mfc='r', ms=3)
  9. for j in arange(len(t)):
  10. # reset x/y-data of point
  11. setp(point[0], data=(x[j], y[j]))
  12. draw() # redraw current figure
  13. ioff() # turn off interactive mode
  14. show()

字符串
所以也许通过使用draw()你可以得到你想要的。我还没有测试过这段代码,我想知道它的行为。

展开查看全部
dkqlctbz

dkqlctbz3#

我在第一次使用show()时也遇到了同样的问题。你还在使用0.99.3版本吗?我最近解决了这个问题,如果你仍然对改变show()的行为感兴趣,试试这个:
我注意到matplotlib下载站点的“新增功能”部分有一段标题为“multiple calls to show supported”的内容。
一个长期存在的要求是支持对show()的多个调用。这很困难,因为很难在操作系统、用户界面工具包和版本之间获得一致的行为。Eric Firing在使show在后端之间合理化方面做了很多工作,使用所需的行为使show引发所有新创建的图形并阻止执行,直到它们被关闭。重复调用show应该引发新创建的图形。Eric已经对他可以访问的用户界面工具包、版本和平台进行了大量测试,但是不可能全部测试,所以请向邮件列表和错误跟踪报告问题。
这是1.0.1版的“新特性”,在写这篇文章的时候,新立得的版本还是0.99.3。我可以从1.0.1版的源代码下载和构建。我还需要额外的软件包来满足依赖性,比如libfreetype6-dev tk-dev tk8.5-dev tcl8.5-dev python-gtk2-dev;你的里程可能会有所不同。
现在我有了matplotlib.__version__ == 1.0.1,下面的代码可以按照我所期望的方式工作:

  1. from matplotlib import pyplot as p
  2. from scipy import eye
  3. p.imshow(eye(3))
  4. p.show()
  5. print 'a'
  6. p.imshow(eye(6))
  7. p.show()
  8. print 'b'
  9. p.imshow(eye(9))
  10. p.show()
  11. print 'c'

字符串

展开查看全部
cgfeq70w

cgfeq70w4#

  1. def onpick(self,event):
  2. print "click"
  3. print 'you pressed', event.canvas
  4. ...
  5. ax.plot(a)
  6. fig.show() # <--- this blocks the entire loop

字符串
试试看:

  1. def onpick(self,event):
  2. print "click"
  3. print 'you pressed', event.canvas
  4. ...
  5. ax.plot(a)
  6. self.draw()
  7. self.update()

展开查看全部
ndh0cuux

ndh0cuux5#

我解决这个问题的方法是永远不要调用close
我很确定你可以在PyQt中控制小部件的透明度。你可以尝试使用Qt而不是matplotlib来控制可见性。我相信其他对matplotlib了解更多的人可以给予比这个更好的答案:D

7kjnsjlb

7kjnsjlb6#

可以通过以下方式创建地物示例:

  1. fig = plt.figure(0)

字符串
并通过操作这个图来绘制你的东西。你可以随时使用fig.show()来显示你的图。

相关问题