def update_particles(particles): animation_chart = QChart() reals = QScatterSeries() pen_reals = reals.pen() pen_reals.setBrush(QtGui.QColor("white")) reals.setMarkerSize(5) reals.setColor(QtGui.QColor("red")) reals.setPen(pen_reals) for particle in particles: reals.append(particle, 0) animation_chart.addSeries(reals) animation_chart.setBackgroundBrush(QtGui.QColor(41, 43, 47)) animation_chart.createDefaultAxes() animation_chart.legend().hide() animation_chart.setContentsMargins(-10, -10, -10, -10) animation_chart.layout().setContentsMargins(0, 0, 0, 0) animation_chart.axisX().setTickCount(17) animation_chart.axisY().setTickCount(3) animation_chart.axisX().setLabelsColor(QtGui.QColor("white")) animation_chart.axisX().setGridLineColor(QtGui.QColor("grey")) animation_chart.axisX().setRange(-4, 12) animation_chart.axisY().setRange(-1, 1) animation_chart.axisY().setLabelsColor(QtGui.QColor("white")) animation_chart.axisY().setGridLineColor(QtGui.QColor("grey")) form.widget_animation.setChart(animation_chart)
def setupChart(self): """Set up the GUI's series and chart.""" # Collect x and y data values from the CSV file x_values, y_values = self.loadCSVFile() # Get the largest x and y values; Used for setting the chart's axes x_max, y_max = max(x_values), max(y_values) # Create numpy arrays from the x and y values x_values = np.array(x_values) y_values = np.array(y_values) # Calculate the regression line coefficients = linearRegression(x_values, y_values) # Create chart object chart = QChart() chart.setTitle("Auto Insurance for Geographical Zones in Sweden") chart.legend().hide() # Create scatter series and add points to the series scatter_series = QScatterSeries() scatter_series.setName("DataPoints") scatter_series.setMarkerSize(9.0) scatter_series.hovered.connect(self.displayPointInfo) for value in range(0, self.row_count - 1): scatter_series.append(x_values[value], y_values[value]) scatter_series.setBorderColor(QColor('#000000')) # Create line series and add points to the series line_series = QLineSeries() line_series.setName("RegressionLine") # Calculate the regression line for x in x_values: y_pred = coefficients[0] + coefficients[1] * x line_series.append(x, y_pred) # Add both series to the chart and create x and y axes chart.addSeries(scatter_series) chart.addSeries(line_series) chart.createDefaultAxes() axis_x = chart.axes(Qt.Horizontal) axis_x[0].setTitleText("Number of Claims") axis_x[0].setRange(0, x_max) axis_x[0].setLabelFormat("%i") axis_y = chart.axes(Qt.Vertical) axis_y[0].setTitleText( "Total Payment in Swedish Kronor (in thousands)") axis_y[0].setRange(0, y_max + 20) # Create QChartView object for displaying the chart chart_view = QChartView(chart) v_box = QVBoxLayout() v_box.addWidget(chart_view) self.setLayout(v_box)
class ChartView(QChartView,QChart): def __init__(self, *args, **kwargs): super(ChartView, self).__init__(*args, **kwargs) self.resize(800, 600) self.setRenderHint(QPainter.Antialiasing) # 抗锯齿 self.chart_init() self.timer_init() def timer_init(self): #使用QTimer,2秒触发一次,更新数据 self.timer = QTimer(self) self.timer.timeout.connect(self.drawLine) self.timer.start(100) def chart_init(self): self.chart = QChart() self.series = QScatterSeries() #设置曲线名称 self.series.setName("实时数据") self.series.setColor(QColor(255,0,0)) self.series.setMarkerSize(20.0) self.series.setPen(QPen(QtCore.Qt.PenStyle.NoPen)) #把曲线添加到QChart的实例中 self.chart.addSeries(self.series) #声明并初始化X轴,Y轴 self.dtaxisX = QDateTimeAxis() self.vlaxisY = QValueAxis() #设置坐标轴显示范围 self.dtaxisX.setMin(QDateTime.currentDateTime().addSecs(-300*1)) self.dtaxisX.setMax(QDateTime.currentDateTime().addSecs(0)) self.vlaxisY.setMin(0) self.vlaxisY.setMax(1500) #设置X轴时间样式 self.dtaxisX.setFormat("MM月dd hh:mm:ss") #设置坐标轴上的格点 self.dtaxisX.setTickCount(6) self.vlaxisY.setTickCount(11) #设置坐标轴名称 self.dtaxisX.setTitleText("时间") self.vlaxisY.setTitleText("量程") #设置网格不显示` #把坐标轴添加到chart中 self.chart.addAxis(self.dtaxisX,Qt.AlignBottom) self.chart.addAxis(self.vlaxisY,Qt.AlignLeft) #把曲线关联到坐标轴 self.series.attachAxis(self.dtaxisX) self.series.attachAxis(self.vlaxisY) self.setChart(self.chart) def drawLine(self): #获取当前时间 bjtime = QDateTime.currentDateTime() #更新X轴坐标 self.dtaxisX.setMin(QDateTime.currentDateTime().addSecs(-300*1)) self.dtaxisX.setMax(QDateTime.currentDateTime().addSecs(0)) #当曲线上的点超出X轴的范围时,移除最早的点 if(self.series.count()>149): self.series.removePoints(0,self.series.count()-149) #产生随即数 yint = random.randint(0,1500) #添加数据到曲线末端 self.series.append(bjtime.toMSecsSinceEpoch(),yint)
def getSeries(self, chart): for i, data_list in enumerate(self.m_dataTable): series = QScatterSeries(chart) for value, _ in data_list: series.append(value) series.setName('Series ' + str(i)) chart.addSeries(series)
def createScatterChart(self): chart = QChart() chart.setTitle("Scatter chart") for i, data_list in enumerate(self.m_dataTable): series = QScatterSeries(chart) for value, _ in data_list: series.append(value) series.setName("Series " + str(i)) chart.addSeries(series) chart.createDefaultAxes() return chart
def addSeries(self, _x2idx: typing.Dict, _idx2x: list, _chart: QChart, _axis_x: QValueAxis, _axis_y: QValueAxis): series = QScatterSeries() series.setName(self.name) for x, y in zip(self.x_list, self.y_list): series.append(_x2idx[x], y) if self.color is not None: series.setColor(self.color) _chart.addSeries(series) _chart.setAxisX(_axis_x, series) _chart.setAxisY(_axis_y, series) if self.show_value: self.createShow()
def addSeries( self, _x2idx: typing.Dict, _idx2x: list, _chart: QChart, _axis_x: QValueAxis, _axis_y: QValueAxis ): series = QScatterSeries() series.setName(self.name) for x, y in zip(self.x_list, self.y_list): series.append(_x2idx[x], y) if self.color is not None: series.setColor(self.color) _chart.addSeries(series) _chart.setAxisX(_axis_x, series) _chart.setAxisY(_axis_y, series) if self.show_value: self.createShow()
def XScatterSeries(data_dict, key_order = None, xkey = None, openGL=False): ''' the first dict in the key_order will be used as the x-axis ''' if key_order==None: key_order = data_dict.keys() series = [] if xkey == None: xkey = list(key_order)[0] for key in key_order-xkey: set = QScatterSeries(); set.setName(key) if openGL: set.setUseOpenGL(True) for i, (itemx, itemy) in enumerate(zip_longest(data_dict[xkey],data_dict[key])): set.append(itemx, itemy) series.append(set) return series
def __drawParetoChart(self): def make_noise(value, noise_size): return value + (noise_size / -2 + noise_size * random.random()) self.__pareto_chart.removeAllSeries() series1 = QScatterSeries() series1.setMarkerShape(QScatterSeries.MarkerShapeCircle) series1.setMarkerSize(5) series1.append(make_noise(23, 2), make_noise(25, 2)) series1.setBrush(QColor(Qt.red)) self.__pareto_chart.addSeries(series1) self.__axisy.setRange(0.0, 100.0) series3 = QScatterSeries() series3.setName("Точка утопии") series3.setMarkerShape(QScatterSeries.MarkerShapeCircle) series3.setMarkerSize(10) series3.append(make_noise(2, 0.5), make_noise(23, 2)) self.__pareto_chart.addSeries(series3) series2 = QScatterSeries() series2.setName("Оптимальный") series2.setMarkerShape(QScatterSeries.MarkerShapeCircle) series2.setMarkerSize(7) series2.append(make_noise(2, 0.5), make_noise(45, 4)) self.__pareto_chart.addSeries(series2) self.__pareto_chart.setAxisX(self.__axisx, series1) self.__pareto_chart.setAxisY(self.__axisy, series1) self.__pareto_chart.setAxisX(self.__axisx, series2) self.__pareto_chart.setAxisY(self.__axisy, series2) self.__pareto_chart.setAxisX(self.__axisx, series3) self.__pareto_chart.setAxisY(self.__axisy, series3)
def appendScatterSeries(self, name, list_x, list_y): ls = QScatterSeries() ls.setName(name) self.series.append(ls) for i in range(len(list_x)): x = float(list_x[i]) y = float(list_y[i]) ls.append(x, y) if self.maxy == None: #Gives first maxy and miny self.maxy = y * 1.01 self.miny = y * 0.99 self.maxx = x * 1.01 self.minx = x * 0.99 if y > self.maxy: self.maxy = y if y < self.miny: self.miny = y if x > self.maxx: self.maxx = x if x < self.minx: self.minx = x
def run_evolution(): range_a = float(str(form.input_a.text())) range_b = float(str(form.input_b.text())) precision = int(str(form.input_d.text())) generations_number = int(str(form.input_t.text())) app.setOverrideCursor(QtCore.Qt.WaitCursor) best_reals, best_binary, best_fxs, local_fxs, _, _ = evolution(range_a, range_b, precision, generations_number, form.checkBox.isChecked()) form.best_table.item(1,0).setText(str(best_reals[len(local_fxs)-1])) form.best_table.item(1,1).setText(''.join(map(str, best_binary[len(local_fxs)-1]))) form.best_table.item(1,2).setText(str(best_fxs[len(local_fxs)-1])) chart = QChart() bests = QLineSeries() pen_best = bests.pen() pen_best.setWidth(1) pen_best.setBrush(QtGui.QColor("red")) bests.setPen(pen_best) for i in range(0, len(local_fxs)): if len(local_fxs[i]) - 1 == 0: fxs = QScatterSeries() fxs.append(i + 0.99, local_fxs[i][0]) pen = fxs.pen() color = QtGui.QColor(random.randint(50,255), random.randint(50,255), random.randint(50,255)) fxs.setColor(color) pen.setColor(color) fxs.setPen(pen) fxs.setMarkerSize(5) else: fxs = QLineSeries() tick = 1 / (len(local_fxs[i]) - 1) for j in range(len(local_fxs[i])): fxs.append(i + j * tick, local_fxs[i][j]) pen = fxs.pen() pen.setWidth(1) pen.setBrush(QtGui.QColor(random.randint(50,255), random.randint(50,255), random.randint(50,255))) fxs.setPen(pen) bests.append(i+1, best_fxs[i]) chart.addSeries(fxs) chart.addSeries(bests) chart.setBackgroundBrush(QtGui.QColor(41, 43, 47)) chart.createDefaultAxes() chart.legend().hide() chart.setContentsMargins(-10, -10, -10, -10) chart.layout().setContentsMargins(0, 0, 0, 0) chart.axisX().setTickCount(11) chart.axisX().setLabelsColor(QtGui.QColor("white")) chart.axisX().setGridLineColor(QtGui.QColor("grey")) chart.axisX().setLabelFormat("%i") chart.axisY().setRange(-2,2) chart.axisY().setLabelsColor(QtGui.QColor("white")) chart.axisY().setGridLineColor(QtGui.QColor("grey")) form.widget.setChart(chart) with open('best_history.csv', 'w', newline='', encoding='utf8') as history_csvfile: history_writer = csv.writer( history_csvfile, delimiter=';', dialect=csv.excel) history_writer.writerow(['Parametry']) history_writer.writerow(['Precyzja: 10^-%d' % precision]) history_writer.writerow(['Iteracje: %d' % generations_number]) history_writer.writerow(['', 'real', 'bin', 'f(real)']) for index, generation in enumerate(range(generations_number)): history_writer.writerow([index, best_reals[generation], best_binary[generation], best_fxs[generation]]) app.restoreOverrideCursor()
class Window(QMainWindow): def __init__(self, landmarkPoints, allPoints, threadEvent): super().__init__() self.title = "Lidar data points" #self.queue = queue self.color = Qt.darkRed self.lmrkPoints = landmarkPoints self.allPoints = allPoints self.event = threadEvent self.left = 500 self.top = 500 self.height = 480 self.width = 640 self.count = 0 self.time = 0 self.label = QLabel(self) self.lmrkBox = QCheckBox("Landmark points", self) self.ptsBox = QCheckBox("Data points", self) self.boxArea = QWidget() self.mainLayout = QGridLayout() self.mainLayout.addWidget(self.lmrkBox, 0, 0) self.mainLayout.addWidget(self.ptsBox, 1, 0) self.mainLayout.setVerticalSpacing(5) self.boxArea.setLayout(self.mainLayout) crote = QDockWidget("Hide", self) crote.setWidget(self.boxArea) self.addDockWidget(Qt.LeftDockWidgetArea, crote) dock = QDockWidget("", self) dock.setWidget(self.label) self.addDockWidget(Qt.LeftDockWidgetArea, dock) self.chart = QChart() self.config_axis() self.series = QScatterSeries(self.chart) self.allSeries = QScatterSeries(self.chart) self.config_series() #self.update() self.timer = QTimer(self) self.view = QChartView(self.chart) self.setCentralWidget( self.view ) # It is needed to create to view because the CentralWidget needs to be a QWidget, and a QChart is not so. self.initWindow() def config_series(self): self.series.setName("Landmark Points") self.allSeries.setName("Data Points") lmrkPen = self.series.pen() pen = self.allSeries.pen() lmrkPen.setWidthF(.2) pen.setWidthF(.2) self.series.setPen(lmrkPen) self.allSeries.setPen(pen) self.series.setColor(Qt.red) self.allSeries.setColor(Qt.blue) self.series.setMarkerShape(1) # 1 - rectangle; 0 - circle # for good visualization, the landmark points should be bigger than normal points self.series.setMarkerSize(8) self.allSeries.setMarkerSize(5) self.label.move(15, 15) def config_axis(self): self.xAxis = QValueAxis() self.yAxis = QValueAxis() self.xAxis.setRange(-XRANGE, XRANGE) self.xAxis.setTitleText("Eixo x") self.yAxis.setRange(-YRANGE, YRANGE) self.yAxis.setTitleText("Eixo y") self.chart.addAxis(self.xAxis, Qt.AlignBottom) self.chart.addAxis(self.yAxis, Qt.AlignLeft) def update(self): self.event.wait() start = time.time() self.label.setText("FPS: {:.2f}".format(1 / (time.time() - self.time))) self.time = time.time() if self.count == 0 and self.lmrkPoints != []: self.series.append(self.lmrkPoints[0][:]) self.allSeries.append(self.allPoints[0][:]) del self.lmrkPoints[:] del self.allPoints[:] self.count = 1 elif self.lmrkPoints != []: self.series.replace(self.lmrkPoints[0][:]) self.allSeries.replace(self.allPoints[0][:]) del self.lmrkPoints[:] del self.allPoints[:] end = time.time() self.event.clear() def hide_show_points(self): self.series.setVisible(not self.series.isVisible()) def hide_show_all_points(self): self.allSeries.setVisible(not self.allSeries.isVisible()) def initWindow(self): print("queue inside myWindow: {}".format(self.lmrkPoints)) self.setGeometry(self.left, self.top, self.width, self.height) self.setWindowTitle(self.title) self.chart.addSeries(self.series) self.chart.addSeries(self.allSeries) self.series.attachAxis(self.xAxis) self.series.attachAxis(self.yAxis) self.allSeries.attachAxis(self.xAxis) self.allSeries.attachAxis(self.yAxis) self.timer.timeout.connect(self.update) self.lmrkBox.stateChanged.connect(self.hide_show_points) self.ptsBox.stateChanged.connect(self.hide_show_all_points) self.timer.start(0) self.show()
def onPlotButtonClicked(self, packets=None): if self.chart: self.chart.removeAllSeries() if packets is None: packets = self.data if not packets: return self.showMessage('Preparing plot ...') name = self.paramNameEdit.text() packet_selection = self.comboBox.currentIndex() xaxis_type = self.xaxisComboBox.currentIndex() data_type = self.dataTypeComboBox.currentIndex() timestamp = [] self.y = [] params = self.paramNameEdit.text() header = packets[0]['header'] current_spid = 0 spid_text = self.spidLineEdit.text() if spid_text: current_spid = int(spid_text) selected_packets=[] if packet_selection == 0: selected_packets=[packets[self.current_row]] elif packet_selection == 1: selected_packets=packets for packet in selected_packets: header = packet['header'] if packet['header']['SPID'] != current_spid: continue params = packet['parameters'] self.walk(name, params, header, timestamp, self.y, xaxis_type, data_type) self.x = [] if not self.y: self.showMessage('No data points') elif self.y: style = self.styleEdit.text() if not style: style = '-' title = '%s' % str(name) desc = self.descLabel.text() if desc: title += '- %s' % desc self.chart.setTitle(title) ylabel = 'Raw value' xlabel = name if data_type == 1: ylabel = 'Engineering / Decompressed value' if xaxis_type == 0: if packet_selection == 1: xlabel = "Packet #" else: xlabel = "Repeat #" self.x = range(0, len(self.y)) if xaxis_type == 1: self.x = [t - timestamp[0] for t in timestamp] xlabel = 'Time -T0 (s)' if xaxis_type != 2: series = QLineSeries() series2 = None for xx, yy in zip(self.x, self.y): series.append(xx, yy) if 'o' in style: series2 = QScatterSeries() for xx, yy in zip(self.x, self.y): series2.append(xx, yy) self.chart.addSeries(series2) self.chart.addSeries(series) axisX = QValueAxis() axisX.setTitleText(xlabel) axisY = QValueAxis() axisY.setTitleText(ylabel) self.chart.setAxisX(axisX) self.chart.setAxisY(axisY) series.attachAxis(axisX) series.attachAxis(axisY) else: nbins = len(set(self.y)) ycounts, xedges = np.histogram(self.y, bins=nbins) series = QLineSeries() for i in range(0, nbins): meanx = (xedges[i] + xedges[i + 1]) / 2. series.append(meanx, ycounts[i]) self.chart.addSeries(series) axisX = QValueAxis() axisX.setTitleText(name) axisY = QValueAxis() axisY.setTitleText("Counts") self.chart.setAxisY(axisY) self.chart.setAxisX(axisX) series.attachAxis(axisX) series.attachAxis(axisY) self.xlabel = xlabel self.ylabel = ylabel self.chartView.setRubberBand(QChartView.RectangleRubberBand) self.chartView.setRenderHint(QtGui.QPainter.Antialiasing) msg = 'Number of data points: {}, Ymin: {}, Ymax: {}'.format( len(self.y), min(self.y), max(self.y)) self.showMessage(msg, 1) self.showMessage('The canvas updated!')
class PriceFigure: def __init__(self, name): self.name = name self.chart_view = QChartView() self.price_time_axis = QDateTimeAxis() self.price_time_axis.setFormat('h:mm') self.price_axis = QValueAxis() self.candle_stick_series = QCandlestickSeries() self.candle_stick_series.setIncreasingColor(Qt.red) self.candle_stick_series.setDecreasingColor(Qt.blue) self.moving_average_series = QLineSeries() self.top_edge_series = QScatterSeries() self.bottom_edge_series = QScatterSeries() self.trend_lines = [] self.short_top_trend_series = QLineSeries() self.short_bottom_trend_series = QLineSeries() self.long_top_trend_series = QLineSeries() self.long_bottom_trend_series = QLineSeries() self.trend_lines.append(self.short_top_trend_series) self.trend_lines.append(self.short_bottom_trend_series) self.trend_lines.append(self.long_top_trend_series) self.trend_lines.append(self.long_bottom_trend_series) self.chart_view.chart().addSeries(self.candle_stick_series) self.chart_view.chart().addSeries(self.moving_average_series) self.chart_view.chart().addSeries(self.top_edge_series) self.chart_view.chart().addSeries(self.bottom_edge_series) self.chart_view.chart().addSeries(self.short_top_trend_series) self.chart_view.chart().addSeries(self.long_top_trend_series) self.chart_view.chart().addSeries(self.short_bottom_trend_series) self.chart_view.chart().addSeries(self.long_bottom_trend_series) self.chart_view.chart().addAxis(self.price_time_axis, Qt.AlignBottom) self.chart_view.chart().addAxis(self.price_axis, Qt.AlignLeft) self.chart_view.chart().legend().hide() self.chart_view.setRenderHint(QPainter.Antialiasing) self.set_marker_color() self.set_trend_line_pen() def set_trend_line_pen(self): brushes = [ QBrush(QColor(255, 0, 0, 90)), QBrush(QColor(0, 0, 255, 90)), QBrush(QColor(205, 56, 47, 255)), QBrush(QColor(0, 153, 213, 255)) ] for i, tl in enumerate(self.trend_lines): tl.setPen(QPen(brushes[i], 4, Qt.DotLine)) def set_marker_color(self): self.top_edge_series.setPen(Qt.black) self.top_edge_series.setBrush(QBrush(QColor(255, 0, 255, 90))) self.bottom_edge_series.setPen(Qt.black) self.bottom_edge_series.setBrush(QBrush(QColor(0, 255, 255, 90))) def set_datetime(self, d): self.chart_datetime = d self.datetime_range = (d.timestamp() * 1000, d.replace(hour=23, minute=59).timestamp() * 1000) start_time = QDateTime() until_time = QDateTime() start_time.setDate(QDate(d.year, d.month, d.day)) until_time.setDate(QDate(d.year, d.month, d.day)) start_time.setTime(QTime(9, 0)) until_time.setTime(QTime(16, 0)) self.price_time_axis.setRange(start_time, until_time) def attach(self): self.price_time_axis.setTickCount(7) self.candle_stick_series.attachAxis(self.price_time_axis) self.candle_stick_series.attachAxis(self.price_axis) self.moving_average_series.attachAxis(self.price_time_axis) self.moving_average_series.attachAxis(self.price_axis) self.top_edge_series.attachAxis(self.price_time_axis) self.top_edge_series.attachAxis(self.price_axis) self.bottom_edge_series.attachAxis(self.price_time_axis) self.bottom_edge_series.attachAxis(self.price_axis) self.short_top_trend_series.attachAxis(self.price_time_axis) self.short_top_trend_series.attachAxis(self.price_axis) self.long_top_trend_series.attachAxis(self.price_time_axis) self.long_top_trend_series.attachAxis(self.price_axis) self.short_bottom_trend_series.attachAxis(self.price_time_axis) self.short_bottom_trend_series.attachAxis(self.price_axis) self.long_bottom_trend_series.attachAxis(self.price_time_axis) self.long_bottom_trend_series.attachAxis(self.price_axis) def in_datetime_range(self, q): return self.datetime_range[0] < q < self.datetime_range[1] def clear_series_data(self): self.candle_stick_series.clear() self.moving_average_series.clear() self.top_edge_series.clear() self.bottom_edge_series.clear() self.short_top_trend_series.clear() self.long_top_trend_series.clear() self.short_bottom_trend_series.clear() self.long_bottom_trend_series.clear() def get_chart_view(self): return self.chart_view def add_moving_average(self, q, price): if self.in_datetime_range(q): self.moving_average_series.append(q, price) def add_candle_stick(self, q, o, h, l, c): if self.in_datetime_range(q): self.candle_stick_series.append(QCandlestickSet(o, h, l, c, q)) def set_price_range(self, price_min, price_max): self.price_axis.setRange(price_min, price_max) tick_count = int( math.ceil((price_max - price_min) / price_min * 100. / 2.0)) self.price_axis.setTickCount(tick_count if tick_count + 1 > 2 else 2) def add_top_edge(self, q, price): if self.in_datetime_range(q): self.top_edge_series.append(q, price) def add_bottom_edge(self, q, price): if self.in_datetime_range(q): self.bottom_edge_series.append(q, price) def add_short_top_trend(self, q, price, draw_horizontal=False): if self.in_datetime_range(q): if draw_horizontal: self.short_top_trend_series.append(q, price) if self.name == 'yesterday': self.short_top_trend_series.append(self.datetime_range[1], price) else: self.short_top_trend_series.append(self.datetime_range[0], price) else: self.short_top_trend_series.append(q, price) def add_long_top_trend(self, q, price, draw_horizontal=False): if self.in_datetime_range(q): if draw_horizontal: self.long_top_trend_series.append(q, price) if self.name == 'yesterday': self.long_top_trend_series.append(self.datetime_range[1], price) else: self.long_top_trend_series.append(self.datetime_range[0], price) else: self.long_top_trend_series.append(q, price) def add_short_bottom_trend(self, q, price, draw_horizontal=False): if self.in_datetime_range(q): if draw_horizontal: self.short_bottom_trend_series.append(q, price) if self.name == 'yesterday': self.short_bottom_trend_series.append( self.datetime_range[1], price) else: self.short_bottom_trend_series.append( self.datetime_range[0], price) else: self.short_bottom_trend_series.append(q, price) def add_long_bottom_trend(self, q, price, draw_horizontal=False): if self.in_datetime_range(q): if draw_horizontal: self.long_bottom_trend_series.append(q, price) if self.name == 'yesterday': self.long_bottom_trend_series.append( self.datetime_range[1], price) else: self.long_bottom_trend_series.append( self.datetime_range[0], price) else: self.long_bottom_trend_series.append(q, price)
def onPlotButtonClicked(self): if self.chart: self.chart.removeAllSeries() if not self.data: return self.showMessage('Preparing plot ...') name = self.paramNameEdit.text() packet_selection = self.comboBox.currentIndex() xaxis_type = self.xaxisComboBox.currentIndex() data_type = self.dataTypeComboBox.currentIndex() timestamp = [] self.y = [] packet_id = self.current_row params = self.data[packet_id]['parameters'] header = self.data[packet_id]['header'] current_spid=header['SPID'] if packet_selection == 0: self.walk( name, params, header, timestamp, self.y, xaxis_type, data_type) elif packet_selection == 1: for packet in self.data: header = packet['header'] if packet['header']['SPID'] != current_spid: continue #only look for parameters in the packets of the same type params = packet['parameters'] self.walk( name, params, header, timestamp, self.y, xaxis_type, data_type) self.x = [] if not self.y: self.showMessage('No data points') elif self.y: style = self.styleEdit.text() if not style: style = '-' title = '%s' % str(name) desc = self.descLabel.text() if desc: title += '- %s' % desc self.chart.setTitle(title) ylabel = 'Raw value' xlabel = name if data_type == 1: ylabel = 'Engineering value' if xaxis_type == 0: xlabel = "Packet #" self.x = range(0, len(self.y)) if xaxis_type == 1: self.x = [t - timestamp[0] for t in timestamp] xlabel = 'Time -T0 (s)' #if xaxis_type != 2: if True: series = QLineSeries() series2 = None # print(y) # print(x) for xx, yy in zip(self.x, self.y): series.append(xx, yy) if 'o' in style: series2 = QScatterSeries() for xx, yy in zip(self.x, self.y): series2.append(xx, yy) self.chart.addSeries(series2) self.chart.addSeries(series) self.showMessage('plotted!') #self.chart.createDefaultAxes() axisX = QValueAxis() axisX.setTitleText(xlabel) axisY = QValueAxis() axisY.setTitleText(ylabel) self.chart.setAxisX(axisX) self.chart.setAxisY(axisY) series.attachAxis(axisX) series.attachAxis(axisY) # histogram #else: # nbins = len(set(self.y)) # ycounts, xedges = np.histogram(self.y, bins=nbins) # series = QLineSeries() # for i in range(0, nbins): # meanx = (xedges[i] + xedges[i + 1]) / 2. # series.append(meanx, ycounts[i]) # # series.append(dataset) # self.chart.addSeries(series) # #self.chart.createDefaultAxes() # self.showMessage('Histogram plotted!') # axisX = QValueAxis() # axisX.setTitleText(name) # axisY = QValueAxis() # axisY.setTitleText("Counts") # self.chart.setAxisY(axisY) # self.chart.setAxisX(axisX) ## series.attachAxis(axisX) # series.attachAxis(axisY) # self.widget.setChart(self.chart) self.xlabel=xlabel self.ylabel=ylabel self.chartView.setRubberBand(QChartView.RectangleRubberBand) self.chartView.setRenderHint(QtGui.QPainter.Antialiasing)
def setData(self, timeData, valueData, chartTypes="Bar"): axisX = QDateTimeAxis() axisX.setFormat("yyyy-MM-dd") if self.chartTypes == "Bar": # Clear all series self.clearAll() self.zoomSeries = QLineSeries(self.chart()) barSeries = QBarSeries(self.chart()) barset = QBarSet("data") barSeries.setBarWidth(0.8) barSeries.append(barset) for td, vd in zip(timeData, valueData): self.zoomSeries.append(td.toMSecsSinceEpoch(), vd) barset.append(valueData) self.zoomSeries.hide() self.chart().addSeries(self.zoomSeries) self.chart().addSeries(barSeries) self.chart().setAxisY(QValueAxis(), self.zoomSeries) axisX.setRange(min(timeData), max(timeData)) self.chart().setAxisX(axisX, self.zoomSeries) elif self.chartTypes == "Scatter": # Clear all series self.clearAll() self.zoomSeries = QLineSeries(self.chart()) scattSeries = QScatterSeries(self.chart()) scattSeries.setMarkerSize(8) for td, vd in zip(timeData, valueData): self.zoomSeries.append(td.toMSecsSinceEpoch(), vd) scattSeries.append(td.toMSecsSinceEpoch(), vd) self.zoomSeries.hide() self.chart().addSeries(self.zoomSeries) self.chart().addSeries(scattSeries) self.chart().setAxisY(QValueAxis(), self.zoomSeries) axisX.setRange(min(timeData), max(timeData)) self.chart().setAxisX(axisX, self.zoomSeries) elif self.chartTypes in ["Line", "PLine"]: self.clearAll() if self.chartTypes == "Line": self.zoomSeries = QLineSeries(self.chart()) else: self.zoomSeries = QSplineSeries(self.chart()) for td, vd in zip(timeData, valueData): self.zoomSeries.append(td.toMSecsSinceEpoch(), vd) self.chart().addSeries(self.zoomSeries) self.chart().setAxisY(QValueAxis(), self.zoomSeries) axisX.setRange(min(timeData), max(timeData)) self.chart().setAxisX(axisX, self.zoomSeries) elif self.chartTypes == "Area": self.clearAll() self.zoomSeries = QLineSeries() self.zoomSeries.setColor(QColor("#666666")) for td, vd in zip(timeData, valueData): self.zoomSeries.append(td.toMSecsSinceEpoch(), vd) areaSeries = QAreaSeries(self.zoomSeries, None) self.chart().addSeries(self.zoomSeries) self.chart().addSeries(areaSeries) self.chart().setAxisY(QValueAxis(), areaSeries) axisX.setRange(min(timeData), max(timeData)) self.chart().setAxisX(axisX, areaSeries) self.zoomSeries.hide() self.mintimeData = min(timeData) self.maxtimeData = max(timeData) self.BtnsWidget.dateRangeEdit.setDateRange([ self.mintimeData.toString("yyyy-MM-dd"), self.maxtimeData.toString("yyyy-MM-dd"), ]) self.updateView()
newChart.setTitle(oldChart.title()) self.setChart(newChart) app = QApplication(sys.argv) ANGULAR_MIN = -100 ANGULAR_MAX = 100 RADIAL_MIN = -100 RADIAL_MAX = 100 series1 = QScatterSeries() series1.setName("scatter") for i in range(ANGULAR_MIN, ANGULAR_MAX + 1, 10): series1.append(i, (float(i) / RADIAL_MAX) * RADIAL_MAX + 8.0) series2 = QSplineSeries() series2.setName("spline") for i in range(ANGULAR_MIN, ANGULAR_MAX + 1, 10): series2.append(i, (float(i) / RADIAL_MAX) * RADIAL_MAX) series3 = QLineSeries() series3.setName("star outer") ad = (ANGULAR_MAX - ANGULAR_MIN) / 8.0 rd = (RADIAL_MAX - RADIAL_MIN) / 3.0 * 1.3 series3.append(ANGULAR_MIN, RADIAL_MAX) series3.append(ANGULAR_MIN + ad * 1, RADIAL_MIN + rd) series3.append(ANGULAR_MIN + ad * 2, RADIAL_MAX) series3.append(ANGULAR_MIN + ad * 3, RADIAL_MIN + rd) series3.append(ANGULAR_MIN + ad * 4, RADIAL_MAX)
class MainLivePlot: def plot_live_data(self): #plot graph if self.forceData.force_filepath == "": #area plot only if self.frameCount != 1: #ignore for image self.plotWindow.liveChart.removeAllSeries() self.plotWindow.liveChartScene.removeItem(self.plotWindow.liveChart) self.plotWindow.liveChartView.resetCachedContent() self.plotWindow.liveChart = QChart() #live chart self.plotWindow.liveChart.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.plotWindow.liveChart.legend().hide() logging.debug('%s', self.plotWindow.liveChartView.size()) w, h = (self.plotWindow.liveChartView.size().width(), self.plotWindow.liveChartView.size().height()) logging.debug('%s, %s', w,h) self.plotWindow.liveChart.setMinimumSize(w, h) self.curve1 = QScatterSeries()#initialise live plot curves self.initialise_live_plot(self.curve1, Qt.blue) #contact area plot logging.debug('%s', self.frameTime.shape) data_ind = "Contact angle" \ if self.analysisMode.currentText() == "Contact Angle Analysis" \ else "Contact area" for k in self.roiDict.keys(): if len(self.roiDict.keys()) > 1 and k == "Default": continue self.curve1.append(self.series_to_polyline(self.frameTime, self.dataDict[k][data_ind])) self.plotWindow.liveChart.addSeries(self.curve1) if self.roi_auto == True: # roi area plot self.curve2 = QScatterSeries() self.initialise_live_plot(self.curve2, Qt.red) for k in self.roiDict.keys(): if len(self.roiDict.keys()) > 1 and k == "Default": continue self.curve2.append(self.series_to_polyline(self.frameTime, self.dataDict[k]["ROI area"])) self.plotWindow.liveChart.addSeries(self.curve2) self.plotWindow.liveChart.createDefaultAxes() self.plotWindow.liveChartScene.addItem(self.plotWindow.liveChart) self.plotWindow.liveChartView.setScene(self.plotWindow.liveChartScene) logging.debug("live plot end") elif self.forceData.plotWidget.fig_close == False: #area and force plot self.forceData.getArea(self.frameTime, self.dataDict) # self.forceData.plotData(self.lengthUnit.currentText()) # self.forceData.toggleAnimation(True) self.forceData.plotImageAnimate(int(self.framePos)) def pauseAnimation(self): if self.forceData.plotWidget.fig_close == False and \ self.forceData.force_filepath != "" and \ self.playStatus == False: self.forceData.toggleAnimation(False) def plot_data(self): #plot graph if self.forceData.force_filepath == "": self.plotWindow.home() #live area data show else: # if self.playStatus == True: #pause video if running (bug) # self.playBtn.click() self.forceData.plotWidget.fig_close = False #area data show # self.forceData.getArea(self.frameTime, self.dataDict) # self.forceData.plotData(self.imageDataUnitDict) self.plotSequence() self.forceData.plotWidget.showWindow() # self.forceData.plotWidget.resize(self.forceData.plotWidget.minimumSizeHint()) def initialise_live_plot(self, curve, color): #initalise live plot pen = curve.pen() pen.setColor(color)#Qt.blue pen.setWidthF(1) curve.setPen(pen) curve.setUseOpenGL(True) curve.setMarkerSize(4.0) def series_to_polyline(self, xdata, ydata): #convert plot data for Qt """Convert series data to QPolygon(F) polyline This code is derived from PythonQwt's function named `qwt.plot_curve.series_to_polyline`""" xsize = len(xdata) ysize = len(ydata) if xsize != ysize: root = Tk() root.withdraw() messagebox.showinfo("Live Plot Error!", "Check force file/video file\n" + \ "Exception: x axis and y axis array sizes don't match") root.destroy() self.playStatus = False polyline = QPolygonF(xsize) pointer = polyline.data() dtype, tinfo = np.float, np.finfo # integers: = np.int, np.iinfo pointer.setsize(2*polyline.size()*tinfo(dtype).dtype.itemsize) memory = np.frombuffer(pointer, dtype) memory[:(xsize-1)*2+1:2] = xdata memory[1:(ysize-1)*2+2:2] = ydata return polyline
class AmzHistoryChart(QWidget): """A chart that graphs the history of an AmazonListing's sales rank, price, and number of offers.""" def __init__(self, parent=None): super(AmzHistoryChart, self).__init__(parent=parent) self.dbsession = Session() self.context_menu_actions = [] self._avg_pointspan = 0 self._max_points = 100 self.source = None self.history = None layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) # Set up the chart self.chart_view = QChartView(self) self.chart_view.setRenderHint(QPainter.Antialiasing) self.chart_view.setContextMenuPolicy(Qt.CustomContextMenu) self.chart_view.customContextMenuRequested.connect(self.context_menu) self.chart = QChart() self.chart.legend().hide() self.chart.setFlags(QGraphicsItem.ItemIsFocusable | QGraphicsItem.ItemIsSelectable) self.chart.installEventFilter(self) self.chart_view.setChart(self.chart) self.layout().addWidget(self.chart_view) # Create the axes rcolor = QColor(50, 130, 220) pcolor = QColor(0, 200, 0) ocolor = QColor(255, 175, 0) self.timeAxis = QDateTimeAxis() self.timeAxis.setFormat('M/dd hh:mm') self.timeAxis.setTitleText('Date/Time') self.chart.addAxis(self.timeAxis, Qt.AlignBottom) self.timeAxis.minChanged.connect(self.on_timeaxis_min_changed) self.rankAxis = QValueAxis() self.rankAxis.setLabelFormat('%\'i') self.rankAxis.setTitleText('Sales Rank') self.rankAxis.setLinePenColor(rcolor) self.rankAxis.setLabelsColor(rcolor) self.chart.addAxis(self.rankAxis, Qt.AlignLeft) self.priceAxis = QValueAxis() self.priceAxis.setLabelFormat('$%.2f') self.priceAxis.setTitleText('Price') self.priceAxis.setLinePenColor(pcolor) self.priceAxis.setLabelsColor(pcolor) self.chart.addAxis(self.priceAxis, Qt.AlignRight) # Create the series self.rankLine = QLineSeries() self.chart.addSeries(self.rankLine) self.rankLine.attachAxis(self.timeAxis) self.rankLine.attachAxis(self.rankAxis) self.rankLine.setColor(rcolor) self.priceLine = QLineSeries() self.chart.addSeries(self.priceLine) self.priceLine.attachAxis(self.timeAxis) self.priceLine.attachAxis(self.priceAxis) self.priceLine.setColor(pcolor) self.salesPoints = QScatterSeries() self.chart.addSeries(self.salesPoints) self.salesPoints.attachAxis(self.timeAxis) self.salesPoints.attachAxis(self.rankAxis) self.salesPoints.setColor(ocolor) def add_context_action(self, action): """Add an action to the chart's context menu.""" self.context_menu_actions.append(action) def add_context_actions(self, actions): """Adds all action in an iterable.""" self.context_menu_actions.extend(actions) def remove_context_action(self, action): """Removes an action from the chart's context menu.""" self.context_menu_actions.remove(action) def context_menu(self, point): """Show a context menu on the chart.""" menu = QMenu(self) menu.addActions(self.context_menu_actions) point = self.chart_view.viewport().mapToGlobal(point) menu.popup(point) def set_source(self, source): """Set the source listing for the graph.""" self.source = source # Update the chart self.rankLine.clear() self.priceLine.clear() self.salesPoints.clear() self.history = None start_date = datetime.utcnow() - timedelta(days=5) self.load_history_from(start_date) self.reset_axes() def load_history_from(self, start_date=datetime.utcfromtimestamp(0)): """Load history data from start-present.""" if not self.source: self._avg_pointspan = 0 return # Get the earliest point already in the chart points = self.rankLine.pointsVector() if points: # The chart is drawn right-to-left, so the last point is the earliest point earliest_msecs = points[-1].x() earliest = datetime.fromtimestamp(earliest_msecs / 1000, timezone.utc) if earliest <= start_date: return else: earliest = datetime.now(timezone.utc) # Get the product history stats if we don't already have them if self.history is None: self.history = dbhelpers.ProductHistoryStats(self.dbsession, self.source.id) # Start adding points to the chart last_row = None for row in self.dbsession.query(AmzProductHistory).\ filter(AmzProductHistory.amz_listing_id == self.source.id, AmzProductHistory.timestamp > start_date.replace(tzinfo=None), AmzProductHistory.timestamp < earliest.replace(tzinfo=None)).\ order_by(AmzProductHistory.timestamp.desc()): # SqlAlchemy returns naive timestamps time = row.timestamp.replace(tzinfo=timezone.utc).timestamp() * 1000 self.rankLine.append(time, row.salesrank or 0) self.priceLine.append(time, row.price or 0) if last_row: # It's possible for salesrank to be None try: slope = (last_row.salesrank - row.salesrank) / (last_row.timestamp.timestamp() - row.timestamp.timestamp()) if slope < -0.3: self.salesPoints.append(last_row.timestamp.replace(tzinfo=timezone.utc).timestamp() * 1000, last_row.salesrank) except (TypeError, AttributeError): pass last_row = row # Calculate the average span between points spans = 0 for p1, p2 in itertools.zip_longest(itertools.islice(points, 0, None, 2), itertools.islice(points, 1, None, 2)): if p1 and p2: spans += abs(p1.x() - p2.x()) self._avg_pointspan = spans // 2 def on_timeaxis_min_changed(self, min): """Respond to a change in the time axis' minimum value.""" # toTime_t() converts to UTC automatically utc_min = datetime.fromtimestamp(min.toTime_t(), timezone.utc) self.load_history_from(start_date=utc_min - timedelta(days=1)) def reset_axes(self): """Resets the chart axes.""" r = self.rankLine.pointsVector() p = self.priceLine.pointsVector() # If there is only one data point, set the min and max to the day before and the day after if len(r) == 1: tmin = QDateTime.fromMSecsSinceEpoch(r[0].x(), Qt.LocalTime).addDays(-1) tmax = QDateTime.fromMSecsSinceEpoch(r[0].x(), Qt.LocalTime).addDays(+1) else: tmin = min(r, key=lambda pt: pt.x(), default=QPointF(QDateTime.currentDateTime().addDays(-1).toMSecsSinceEpoch(), 0)).x() tmax = max(r, key=lambda pt: pt.x(), default=QPointF(QDateTime.currentDateTime().addDays(+1).toMSecsSinceEpoch(), 0)).x() tmin = QDateTime.fromMSecsSinceEpoch(tmin, Qt.LocalTime) tmax = QDateTime.fromMSecsSinceEpoch(tmax, Qt.LocalTime) self.timeAxis.setMin(tmin) self.timeAxis.setMax(tmax) # Find the min and max values of the series min_point = lambda pts: min(pts, key=lambda pt: pt.y(), default=QPointF(0, 0)) max_point = lambda pts: max(pts, key=lambda pt: pt.y(), default=QPointF(0, 0)) rmin = min_point(r) rmax = max_point(r) pmin = min_point(p) pmax = max_point(p) # Scale the mins and maxes to 'friendly' values scalemin = lambda v, step: ((v - step / 2) // step) * step scalemax = lambda v, step: ((v + step / 2) // step + 1) * step # The the axis bounds rmin = max(scalemin(rmin.y(), 1000), 0) rmax = scalemax(rmax.y(), 1000) pmin = max(scalemin(pmin.y(), 5), 0) pmax = scalemax(pmax.y(), 5) self.rankAxis.setMin(rmin) self.rankAxis.setMax(rmax) self.priceAxis.setMin(pmin) self.priceAxis.setMax(pmax) def eventFilter(self, watched, event): """Intercept and handle mouse events.""" if event.type() == QEvent.GraphicsSceneWheel and event.orientation() == Qt.Vertical: factor = 0.95 if event.delta() < 0 else 1.05 self.chart.zoom(factor) return True if event.type() == QEvent.GraphicsSceneMouseDoubleClick: self.chart.zoomReset() self.reset_axes() return True if event.type() == QEvent.GraphicsSceneMouseMove: delta = event.pos() - event.lastPos() self.chart.scroll(-delta.x(), delta.y()) return True return False