8 from cStringIO
import StringIO
10 from cv_bridge
import CvBridge
11 from distutils.version
import LooseVersion
12 from matplotlib.figure
import Figure
14 import python_qt_binding
15 from python_qt_binding
import loadUi
16 from python_qt_binding.QtCore
import Qt
17 from python_qt_binding.QtCore
import QTimer
18 from python_qt_binding.QtCore
import Slot
19 from python_qt_binding.QtGui
import QIcon
26 from sensor_msgs.msg
import Image
28 from jsk_recognition_msgs.msg
import HistogramWithRange
31 if LooseVersion(python_qt_binding.QT_BINDING_VERSION).version[0] >= 5:
32 from python_qt_binding.QtWidgets
import QSizePolicy
33 from python_qt_binding.QtWidgets
import QVBoxLayout
34 from python_qt_binding.QtWidgets
import QWidget
36 from matplotlib.backends.backend_qt5agg
import FigureCanvasQTAgg \
41 sys.modules[
'_thread'] = thread
42 from matplotlib.backends.backend_qt5agg
import FigureCanvasQTAgg \
45 from matplotlib.backends.backend_qt5agg
import NavigationToolbar2QTAgg \
48 from matplotlib.backends.backend_qt5agg
import NavigationToolbar2QT \
51 from python_qt_binding.QtGui
import QSizePolicy
52 from python_qt_binding.QtGui
import QVBoxLayout
53 from python_qt_binding.QtGui
import QWidget
55 from matplotlib.backends.backend_qt4agg
import FigureCanvasQTAgg \
60 sys.modules[
'_thread'] = thread
61 from matplotlib.backends.backend_qt4agg
import FigureCanvasQTAgg \
64 from matplotlib.backends.backend_qt4agg
import NavigationToolbar2QTAgg \
67 from matplotlib.backends.backend_qt4agg
import NavigationToolbar2QT \
75 if not self.field_evals:
77 for f
in self.field_evals:
82 "{0} index error for: {1}".format(
83 self.name, str(val).replace(
'\n',
', ')))
86 "{0} value was not numeric: {1}".format(
92 super(HistogramPlot, self).
__init__(context)
93 self.setObjectName(
'HistogramPlot')
96 context.add_widget(self.
_widget)
99 parser = argparse.ArgumentParser(
100 prog=
'rqt_histogram_plot', add_help=
False)
101 HistogramPlot.add_arguments(parser)
102 args = parser.parse_args(argv)
107 group = parser.add_argument_group(
'Options for rqt_histogram plugin')
109 'topics', nargs=
'?', default=[], help=
'Topics to plot')
113 _redraw_interval = 40
116 super(HistogramPlotWidget, self).
__init__()
117 self.setObjectName(
'HistogramPlotWidget')
118 rp = rospkg.RosPack()
119 ui_file = os.path.join(rp.get_path(
'jsk_rqt_plugins'),
120 'resource',
'plot_histogram.ui')
121 loadUi(ui_file, self)
123 self.subscribe_topic_button.setIcon(QIcon.fromTheme(
'add'))
124 self.pause_button.setIcon(QIcon.fromTheme(
'media-playback-pause'))
125 self.clear_button.setIcon(QIcon.fromTheme(
'edit-clear'))
127 self.data_plot_layout.addWidget(self.
data_plot)
129 self._topic_completer.update_topics()
131 self.data_plot.dropEvent = self.
dropEvent 132 self.data_plot.dragEnterEvent = self.dragEnterEvent
138 self._update_plot_timer.timeout.connect(self.
update_plot)
143 if event.mimeData().hasText():
144 topic_name = str(event.mimeData().text())
146 droped_item = event.source().selectedItems()[0]
147 topic_name = str(droped_item.data(0, Qt.UserRole))
152 if self.subscribe_topic_button.isEnabled():
162 topic_name +
"/histogram_image", Image, queue_size=1)
167 self._rosdata.close()
168 self.data_plot.clear()
171 rospy.logwarn(
"%s is already subscribed", topic_name)
177 self._update_plot_timer.stop()
181 self.data_plot.clear()
190 data_x, data_y = self._rosdata.next()
194 axes = self.data_plot._canvas.axes
196 if isinstance(data_y[-1], HistogramWithRange):
197 xs = [y.count
for y
in data_y[-1].bins]
198 pos = [y.min_value
for y
in data_y[-1].bins]
199 widths = [y.max_value - y.min_value
for y
in data_y[-1].bins]
200 axes.set_xlim(xmin=pos[0], xmax=pos[-1] + widths[-1])
201 elif isinstance(data_y[-1], collections.Sequence):
203 pos = np.arange(len(xs))
204 widths = [1] * len(xs)
205 axes.set_xlim(xmin=0, xmax=len(xs))
208 "Topic/Field name '%s' has unsupported '%s' type." 209 "List of float values and " 210 "jsk_recognition_msgs/HistogramWithRange are supported." 212 self._rosdata.sub.data_class))
215 for p, x, w
in zip(pos, xs, widths):
216 axes.bar(p, x, color=
'r', align='center', width=w)
218 self.data_plot._canvas.draw()
220 self.data_plot._canvas.figure.savefig(buffer, format=
"png")
222 img_array = np.asarray(bytearray(buffer.read()), dtype=np.uint8)
223 if LooseVersion(cv2.__version__).version[0] < 3:
224 iscolor = cv2.CV_LOAD_IMAGE_COLOR
226 iscolor = cv2.IMREAD_COLOR
227 img = cv2.imdecode(img_array, iscolor)
228 self.pub_image.publish(self.cv_bridge.cv2_to_imgmsg(img,
"bgr8"))
235 self.
axes = self.figure.add_subplot(111)
236 self.figure.tight_layout()
237 self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
238 self.updateGeometry()
242 self.figure.tight_layout()
245 super(MatHistogramPlot, self).
__init__(parent)
257 self._canvas.axes.cla()
def __init__(self, context)
def __init__(self, parent=None)
def resizeEvent(self, event)
def _parse_args(self, argv)
def __init__(self, parent=None)
def add_arguments(parser)