11 from cStringIO
import StringIO
13 from io
import BytesIO
as StringIO
15 from cv_bridge
import CvBridge
16 from distutils.version
import LooseVersion
17 from matplotlib.figure
import Figure
19 import python_qt_binding
20 from python_qt_binding
import loadUi
21 from python_qt_binding.QtCore
import Qt
22 from python_qt_binding.QtCore
import QTimer
23 from python_qt_binding.QtCore
import Slot
24 from python_qt_binding.QtGui
import QIcon
31 from sensor_msgs.msg
import Image
33 from jsk_recognition_msgs.msg
import HistogramWithRange
36 if LooseVersion(python_qt_binding.QT_BINDING_VERSION).version[0] >= 5:
37 from python_qt_binding.QtWidgets
import QSizePolicy
38 from python_qt_binding.QtWidgets
import QVBoxLayout
39 from python_qt_binding.QtWidgets
import QWidget
41 from matplotlib.backends.backend_qt5agg
import FigureCanvasQTAgg \
46 sys.modules[
'_thread'] = thread
47 from matplotlib.backends.backend_qt5agg
import FigureCanvasQTAgg \
50 from matplotlib.backends.backend_qt5agg
import NavigationToolbar2QTAgg \
53 from matplotlib.backends.backend_qt5agg
import NavigationToolbar2QT \
56 from python_qt_binding.QtGui
import QSizePolicy
57 from python_qt_binding.QtGui
import QVBoxLayout
58 from python_qt_binding.QtGui
import QWidget
60 from matplotlib.backends.backend_qt4agg
import FigureCanvasQTAgg \
65 sys.modules[
'_thread'] = thread
66 from matplotlib.backends.backend_qt4agg
import FigureCanvasQTAgg \
69 from matplotlib.backends.backend_qt4agg
import NavigationToolbar2QTAgg \
72 from matplotlib.backends.backend_qt4agg
import NavigationToolbar2QT \
80 if not self.field_evals:
82 for f
in self.field_evals:
87 "{0} index error for: {1}".format(
88 self.name, str(val).replace(
'\n',
', ')))
91 "{0} value was not numeric: {1}".format(
97 super(HistogramPlot, self).
__init__(context)
98 self.setObjectName(
'HistogramPlot')
101 context.add_widget(self.
_widget)
104 parser = argparse.ArgumentParser(
105 prog=
'rqt_histogram_plot', add_help=
False)
106 HistogramPlot.add_arguments(parser)
107 args = parser.parse_args(argv)
112 group = parser.add_argument_group(
'Options for rqt_histogram plugin')
114 'topics', nargs=
'?', default=[], help=
'Topics to plot')
118 _redraw_interval = 40
121 super(HistogramPlotWidget, self).
__init__()
122 self.setObjectName(
'HistogramPlotWidget')
123 rp = rospkg.RosPack()
124 ui_file = os.path.join(rp.get_path(
'jsk_rqt_plugins'),
125 'resource',
'plot_histogram.ui')
126 loadUi(ui_file, self)
128 self.subscribe_topic_button.setIcon(QIcon.fromTheme(
'add'))
129 self.pause_button.setIcon(QIcon.fromTheme(
'media-playback-pause'))
130 self.clear_button.setIcon(QIcon.fromTheme(
'edit-clear'))
132 self.data_plot_layout.addWidget(self.
data_plot)
137 self.
data_plot.dragEnterEvent = self.dragEnterEvent
148 if event.mimeData().hasText():
149 topic_name = str(event.mimeData().text())
151 droped_item = event.source().selectedItems()[0]
152 topic_name = str(droped_item.data(0, Qt.UserRole))
157 if self.subscribe_topic_button.isEnabled():
167 topic_name +
"/histogram_image", Image, queue_size=1)
176 rospy.logwarn(
"%s is already subscribed", topic_name)
195 data_x, data_y = self.
_rosdata.next()
201 if isinstance(data_y[-1], HistogramWithRange):
202 xs = [y.count
for y
in data_y[-1].bins]
203 pos = [y.min_value
for y
in data_y[-1].bins]
204 widths = [y.max_value - y.min_value
for y
in data_y[-1].bins]
205 axes.set_xlim(xmin=pos[0], xmax=pos[-1] + widths[-1])
206 elif isinstance(data_y[-1], collections.Sequence):
208 pos = np.arange(len(xs))
209 widths = [1] * len(xs)
210 axes.set_xlim(xmin=0, xmax=len(xs))
213 "Topic/Field name '%s' has unsupported '%s' type."
214 "List of float values and "
215 "jsk_recognition_msgs/HistogramWithRange are supported."
220 for p, x, w
in zip(pos, xs, widths):
221 axes.bar(p, x, color=
'r', align=
'center', width=w)
225 self.
data_plot._canvas.figure.savefig(buffer, format=
"png")
227 img_array = np.asarray(bytearray(buffer.read()), dtype=np.uint8)
228 if LooseVersion(cv2.__version__).version[0] < 3:
229 iscolor = cv2.CV_LOAD_IMAGE_COLOR
231 iscolor = cv2.IMREAD_COLOR
232 img = cv2.imdecode(img_array, iscolor)
240 self.
axes = self.figure.add_subplot(111)
241 self.figure.tight_layout()
242 self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
243 self.updateGeometry()
247 self.figure.tight_layout()
250 super(MatHistogramPlot, self).
__init__(parent)
262 self._canvas.axes.cla()