def __init__(self): super(XAxis, self).__init__() # 创建图表 chart = QtChart.QChart() chart.setTitle('自定义X轴') data_table = random_data_table() # 获取随机生成的数据作图 for i, data_list in enumerate(data_table): series = QtChart.QLineSeries() for value, name in data_list: series.append(*value) series.setName("Series " + str(i)) chart.addSeries(series) chart.createDefaultAxes() # 自定义x轴 series = chart.series() axis = QtChart.QCategoryAxis( chart, labelsPosition=QtChart.QCategoryAxis.AxisLabelsPositionOnValue) min_x = chart.axisX().min() max_x = chart.axisX().max() tick_count = chart.axisX().tickCount() if tick_count < 2: axis.append("LABEL0", min_x) else: step_x = (max_x - min_x) / (tick_count - 1) for i in range(tick_count): axis.append("LABEL%s" % i, min_x + i * step_x) chart.setAxisX(axis, series[0]) # 图表加入容器 self.setChart(chart)
def __init__(self): super(YAxis, self).__init__() # 创建图表 chart = QtChart.QChart() chart.setTitle('自定义添加右侧Y轴') data_table = random_data_table() # 获取随机生成的数据作图 for i, data_list in enumerate(data_table): series = QtChart.QLineSeries() for value, name in data_list: series.append(*value) series.setName("Series " + str(i)) chart.addSeries(series) chart.createDefaultAxes() # 自定义y轴 series = chart.series() y_category = ['周%d' % i for i in range(1, 8)] axisy = QtChart.QCategoryAxis( chart, labelsPosition=QtChart.QCategoryAxis.AxisLabelsPositionOnValue) axisy.setGridLineVisible(False) axisy.setTickCount(len(y_category)) min_y = chart.axisY().min() max_y = chart.axisY().max() tick_count = axisy.tickCount() if tick_count < 2: axisy.append(y_category[0]) else: step_y = (max_y - min_y) / (tick_count - 1) for i in range(tick_count): axisy.append(y_category[i], min_y + step_y * i) chart.addAxis(axisy, Qt.AlignRight) # 在右侧添加轴 series[0].attachAxis(axisy) self.setChart(chart)
def set_zones(self, zones): # Use QBarCategoryAxis instead of QCategoryAxis because the # latter allows putting values between categoreies instead of # centring them. cat_axis = self.x_axis self.removeAxis(cat_axis) cat_axis = QtChart.QCategoryAxis(self) cat_axis.setLabelsPosition( QtChart.QCategoryAxis.AxisLabelsPositionOnValue) # Hide the start value because zones[0] does its job cat_axis.setStartValue(float("-inf")) # Add initial label, handling negative infinity. if zones[0] == float("-inf"): cat_axis.append("\u2212\u221e", -0.5) else: zone_num = self.unit_system.encode(zones[0], "speed") cat_axis.append(number_formats.maybe_as_int(zone_num), -0.5) # Add axis labels for position, zone in enumerate(zones[1:-1]): zone_num = self.unit_system.encode(zone, "speed") cat_axis.append(number_formats.maybe_as_int(zone_num), position + 0.5) # Add final label. This should usually be infinity. if zones[-1] == float("inf"): cat_axis.append("\u221e", len(zones) - 1.5) else: zone_num = self.unit_system.encode(zones[-1], "speed") cat_axis.append(number_formats.maybe_as_int(zone_num), len(zones) - 1.5) cat_axis.setRange(-0.5, len(zones) - 1.5) # One less bar than there are zones borders series = self.series()[0] bar_set = series.barSets()[0] if bar_set.count() > len(zones) - 1: bar_set.remove(0, bar_set.count() - len(zones) + 1) elif bar_set.count() < len(zones) - 1: for _ in range(len(zones) - 1 - bar_set.count()): bar_set.append(0) self.addAxis(cat_axis, Qt.AlignBottom) series.attachAxis(cat_axis) self.set_axis_dimensions("speed", "Time (min)")
def SetLineSeries(self, data_x, data_y, data_y_2=None, chart_name=''): self.chart = QtChart.QChart() #self.chart.setTheme(QtChart.QChart.ChartThemeDark) series = QtChart.QLineSeries() for index in range(len(data_y)): series.append(index, data_y[index]) self.chart.addSeries(series) axisX = QtChart.QCategoryAxis() axisX.setRange(-1, len(data_y) + 1) axisX.setStartValue(0) for index in range(0, len(data_x)): axisX.append(data_x[index], index) axisX.setLabelsAngle(90) #axisX.setTickCount(10) axisX.setLabelsPosition( QtChart.QCategoryAxis.AxisLabelsPositionOnValue) #self.chart.setAxisX(axisX,series) self.chart.addAxis(axisX, QtCore.Qt.AlignBottom) series.attachAxis(axisX) axisY = QtChart.QValueAxis() axisY.setRange(data_y.min(), data_y.max()) axisY.setTickCount(10) self.chart.addAxis(axisY, QtCore.Qt.AlignLeft) #self.chart.setAxisY(axisY,series) series.attachAxis(axisY) if data_y_2 is not None: axisY2 = QtChart.QValueAxis() axisY2.setRange(data_y_2.min(), data_y_2.max()) axisY2.setTickCount(10) self.chart.addAxis(axisY2, QtCore.Qt.AlignRight) series2 = QtChart.QLineSeries() for index in range(len(data_y_2)): series2.append(index, data_y_2[index]) self.chart.addSeries(series2) series2.attachAxis(axisX) series2.attachAxis(axisY2) self.chart.setTitle(chart_name)
def _chartView(self): self.chart = QtChart.QChart() axisX = QtChart.QCategoryAxis(labelsPosition=QtChart.QCategoryAxis.AxisLabelsPositionOnValue, startValue=900.0) axisX.setTitleText("Wavelength (nm)") axisX.setRange(900, 1700) axisX.setTickCount(9) axisX.setLabelsFont(QtGui.QFont("Times", 12)) axisX.append("900", 900.0) axisX.append("1000", 1000) axisX.append("1100", 1100) axisX.append("1200", 1200) axisX.append("1300", 1300) axisX.append("1400", 1400) axisX.append("1500", 1500) axisX.append("1600", 1600) axisX.append("1700", 1700) self.chart.addAxis(axisX, QtCore.Qt.AlignBottom) self.axisY = QtChart.QValueAxis() self.axisY.setTitleText("Absorbance") self.axisY.setLabelFormat("%.2f") self.axisY.setRange(-5, 5) self.axisY.setLabelsFont(QtGui.QFont("Times", 12)) self.chart.addAxis(self.axisY, QtCore.Qt.AlignLeft) self.chart.legend().setVisible(False) self.chartView = QtChart.QChartView(self.widget_plot) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.chartView.sizePolicy().hasHeightForWidth()) self.chartView.setSizePolicy(sizePolicy) self.chartView.setMinimumSize(680, 480) self.chartView.setMouseTracking(True) self.chartView.setAcceptDrops(False) self.chartView.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContentsOnFirstShow) self.chartView.setObjectName("chartView") self.chartView.setChart(self.chart)
def __init__(self): super(TopXAxis, self).__init__() # 创建图表 chart = QtChart.QChart() chart.setTitle('自定义Top-X轴') data_table = random_data_table() # 获取随机生成的数据作图 for i, data_list in enumerate(data_table): series = QtChart.QLineSeries() for value, name in data_list: series.append(*value) series.setName("Series " + str(i)) chart.addSeries(series) chart.createDefaultAxes() # 自定义top-x轴 series = chart.series() x_category = ['%d月' % i for i in range(1, 9)] axis_x = QtChart.QCategoryAxis( chart, labelsPosition=QtChart.QCategoryAxis.AxisLabelsPositionOnValue) axis_x.setGridLineVisible(False) # 隐藏网格线条 axis_x.setTickCount(len(x_category)) # 设置刻度个数 # 强制修改原x轴的刻度个数与自定义上x轴刻度个数一直 chart.axisX().setTickCount(len(x_category)) min_x = chart.axisX().min() max_x = chart.axisX().max() tick_count = chart.axisX().tickCount() print(tick_count) if tick_count < 2: axis_x.append("LABEL0", min_x) else: step_x = (max_x - min_x) / (tick_count - 1) for i in range(tick_count): axis_x.append(x_category[i], min_x + step_x * i) chart.addAxis(axis_x, Qt.AlignTop) series[0].attachAxis(axis_x) # 图表在容器中显示 self.setChart(chart)
def updateCandleChart(self, data, N): """Update candle chart display. :param data: numpy array representing candles :param N: number of candles in the array """ if data is None or data == []: return timestamps = data[0, -N:].astype(int).tolist() open = data[1, -N:].tolist() high = data[2, -N:].tolist() low = data[3, -N:].tolist() close = data[4, -N:].tolist() # remove candlestick data if self.candlestickSeries.count() > 0: self.candlestickSeries.remove(self.candlestickSeries.sets()) # add new candlestick data for i, ts in enumerate(timestamps): candle_set = QtChart.QCandlestickSet(open[i], high[i], low[i], close[i], timestamp=ts) self.setCandleColors(candle_set) self.candlestickSeries.append(candle_set) # set candlestick time axes (hidden) axisXtime = QtChart.QBarCategoryAxis() axisXtime.setCategories([str(int(x / 1000)) for x in timestamps]) axisXtime.setGridLineVisible(False) axisXtime.hide() self.ax = QtChart.QValueAxis() self.ax.setRange(0, len(axisXtime)) self.ax.setGridLineVisible(False) self.ax.hide() # set pen for lines and grid lines line_pen = QtGui.QPen(QtGui.QColor(0, 0, 0), 0.5) grid_line_pen = QtGui.QPen(QtGui.QColor(80, 80, 80), 0.5) # set visible time axes with selected time ticks axisXticks = QtChart.QCategoryAxis() axisXticks.setLabelsPosition( QtChart.QCategoryAxis.AxisLabelsPositionOnValue) for ts, index in self.extractNiceCategories(timestamps): axisXticks.append(ts, index) axisXticks.setGridLineVisible(True) axisXticks.setGridLinePen(grid_line_pen) axisXticks.setLinePen(line_pen) axisXticks.setStartValue(-1) # set y axes (prices) max_val = max(high) min_val = min(low) self.ay = QtChart.QValueAxis() self.ay.setGridLinePen(grid_line_pen) self.ay.setLinePen(line_pen) self.ay.setMax(max_val) self.ay.setMin(min_val) self.ay.applyNiceNumbers() # set y axes font font = self.ay.labelsFont() font.setPointSize(8) self.ay.setLabelsFont(font) # remove old axes for axis in self.candlestickSeries.attachedAxes(): self.candlestickSeries.detachAxis(axis) self.removeAxis(axis) # add updated axes self.addAxis(axisXtime, QtCore.Qt.AlignTop) self.addAxis(axisXticks, QtCore.Qt.AlignBottom) self.addAxis(self.ax, QtCore.Qt.AlignBottom) self.addAxis(self.ay, QtCore.Qt.AlignRight) # attach updated axes to data series self.candlestickSeries.attachAxis(axisXtime) self.candlestickSeries.attachAxis(axisXticks) self.candlestickSeries.attachAxis(self.ay) # update hover line x axes for axis in self.hoverLine.attachedAxes(): self.hoverLine.detachAxis(axis) self.hoverLine.attachAxis(self.ay)
def create_chart(parent, data, title, axis_data=None, chart_type='pie'): # Create Pie Chart if chart_type == 'pie': # Create the data series and initialize it default_series = QtChart.QPieSeries() for (name, value, color, percentage) in data: sl = default_series.append(name, value) sl.setLabel(f"{name}\n({percentage:.2f}%)") sl.setBrush(color) # Modify series default_series.setPieSize(0.75) default_series.setLabelsVisible() default_series.setLabelsPosition(QtChart.QPieSlice.LabelOutside) # Create the chart chart = QtChart.QChart() chart.addSeries(default_series) chart.createDefaultAxes() chart.setAnimationOptions(QtChart.QChart.AllAnimations) chart.setTitle(title) chart.legend().setVisible(False) #chart.legend().setAlignment(QtCore.Qt.AlignBottom) chart.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(225, 225, 225))) # Initialize a chart view chartview = QtChart.QChartView(chart) chartview.setRenderHint(QtGui.QPainter.Antialiasing) chartview.setMinimumSize(QtCore.QSize(600, 400)) chartview.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) return chartview # Line Chart else: default_series = QtChart.QLineSeries() for (x, y) in data: sl = default_series.append(x, y) # Create chart chart = QtChart.QChart() chart.addSeries(default_series) chart.setAnimationOptions(QtChart.QChart.SeriesAnimations) chart.setTitle(title) chart.legend().setVisible(False) chart.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(225, 225, 225))) if axis_data is not None: axis_x = QtChart.QCategoryAxis() # Y-axis axis_x.setRange(axis_data['X']['Min'], axis_data['X']['Max']) axis_x.setTitleText(axis_data['X']['Title']) cur_tick = axis_data['X']['Max'] * 0.1 for i in range(len(axis_data['X']['Labels'])): axis_x.append(f"{axis_data['X']['Labels'][i]}", cur_tick) cur_tick += (float(axis_data['X']['Max']) / len(axis_data['X']['Labels'])) chart.addAxis(axis_x, QtCore.Qt.AlignBottom) axis_y = QtChart.QCategoryAxis() # Y-axis axis_y.setTitleText(axis_data['Y']['Title']) axis_y.setRange(axis_data['Y']['Min'], axis_data['Y']['Max']) axis_y.append('Easy', float(axis_data['Y']['Max']) * 0.1) axis_y.append('Moderate', float(axis_data['Y']['Max']) * 0.9) axis_y.append('Difficult', float(axis_data['Y']['Max']) * 1.3) chart.addAxis(axis_y, QtCore.Qt.AlignLeft) default_series.attachAxis(axis_x) default_series.attachAxis(axis_y) chartview = QtChart.QChartView(chart) chartview.setRenderHint(QtGui.QPainter.Antialiasing) chartview.setMinimumSize(QtCore.QSize(600, 400)) chartview.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) return chartview
def __init__(self): super(LineStackChart, self).__init__() self.chart = QtChart.QChart() # chart.setAcceptHoverEvents(True) # 接受鼠标悬浮事件 # chart.setAnimationOptions(QtChart.QChart.SeriesAnimations) # 数据集 data_table = [["邮件营销", [120, 432, 101, 134, 90, 230, 210]], ["联盟广告", [220, 182, 491, 234, 290, 330, 310]], ["视频广告", [150, 232, 201, 154, 190, 330, 410]], ["直接访问", [320, 332, 301, 334, 390, 330, 320]], ["搜索引擎", [820, 532, 901, 934, 690, 480, 920]]] for series_name, data_list in data_table: # 每个数据集创建一条线 series = QtChart.QLineSeries() for index, value in enumerate(data_list): series.append(index, value) series.setName(series_name) # 设置图例 series.setPointsVisible(True) # 设置点可见 series.hovered.connect(self.series_hovered) # 鼠标悬停信号连接 self.chart.addSeries(series) # 各线加入图表 # 图表chart设置 self.chart.setTitle("QChart鼠标交互") self.chart.createDefaultAxes() # 使用默认轴 # 设置X轴Y轴 axis_X = self.chart.axisX() axis_Y = self.chart.axisY() axis_X.setTickCount(len(data_table[0][1])) # x轴刻度数量 axis_Y.setTickCount(len(data_table[0][1])) # y轴刻度数量 # axis_X.setGridLineVisible(False) # 隐藏x轴竖向线条 axis_Y.setRange(0, 1000) # 自定义X轴 axis_label = QtChart.QCategoryAxis( self.chart, labelsPosition=QtChart.QCategoryAxis.AxisLabelsPositionOnValue) axis_label.setGridLineVisible(False) # 设置竖向线条不可见 min_x = axis_X.min() max_x = axis_X.max() step = (max_x - min_x) / (len(data_table[0][1]) - 1) # x轴间距 self.x_category = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] for i in range(len(self.x_category)): axis_label.append(self.x_category[i], min_x + i * step) self.chart.setAxisX(axis_label, self.chart.series()[-1]) # 图例legend设置 legend = self.chart.legend() legend.setMarkerShape(QtChart.QLegend.MarkerShapeFromSeries) # 由线条设置图例 # 绑定图例信号(鼠标动作) for marker in legend.markers(): marker.clicked.connect(self.legend_clicked) # 鼠标点击信号 marker.hovered.connect(self.legend_hovered) # 鼠标悬停信号 # 图线抗锯齿 self.setRenderHint(QPainter.Antialiasing) # 设置图表在容器上 self.setChart(self.chart) # 线条对象 self.line_item = QtWidgets.QGraphicsLineItem(self.chart) # 提示块 self.tips_tool = GraphicsProxyWidget(self.chart) # 一些固定计算,减少mouseMoveEvent中的计算量 # 获取x和y轴的最小最大值 # axisX, axisY = self.chart.axisX(), self.chart.axisY() # self.min_x, self.max_x = axisX.min(), axisX.max() # self.min_y, self.max_y = axisY.min(), axisY.max() self.min_x, self.max_x = min_x, max_x self.min_y, self.max_y = axis_Y.min(), axis_Y.max()