def lines_stacked(name, table_df, x_bottom_cols, y_left_cols, y_right_cols, legend_labels, tick_count): """ 折线堆叠图 :param name: 图表名称 :param table_df: 用于画图的pandas DataFrame对象 :param x_bottom_cols: 下轴列索引列表 :param y_left_cols: 左轴列索引列表 :param y_right_cols: 右轴列索引列表 :param legend_labels: 图例名称标签列表 :param tick_count: 横轴刻度标签数 :return: QChart实例 """ """ 过滤轴 """ for y_left_col in y_left_cols: if is_datetime64_any_dtype(table_df[y_left_col]): # 如果是时间轴 y_left_cols.remove(y_left_col) for y_right_col in y_right_cols: if is_datetime64_any_dtype(table_df[y_right_col]): # 如果是时间轴 y_right_cols.remove(y_right_col) # 将x轴转为字符串 x_bottom = x_bottom_cols[0] # x轴列 if is_datetime64_any_dtype(table_df[x_bottom]): # 如果x轴是时间轴 table_df[x_bottom] = table_df[x_bottom].apply( lambda x: x.strftime('%Y-%m-%d')) else: # x轴非时间轴 table_df[x_bottom] = table_df[x_bottom].apply(lambda x: str(x)) font = QFont() # 轴文字风格 font.setPointSize(7) # 轴标签文字大小 chart = QChart() # 图表实例 chart.layout().setContentsMargins(0, 0, 0, 0) # chart的外边距 chart.setMargins(QMargins(15, 5, 15, 0)) # chart内边距 chart.setTitle(name) # chart名称 """ x轴 """ axis_x_bottom = QCategoryAxis( chart, labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue) axis_x_bottom.setLabelsAngle(-90) # 逆时针旋转90度 axis_x_bottom.setLabelsFont(font) # 设置字体样式 axis_x_bottom.setGridLineVisible(False) # 竖向连接线不可见 chart.addAxis(axis_x_bottom, Qt.AlignBottom) # 加入坐标x轴 has_x_labels = False # 收集x轴刻度的开关 chart.x_labels = list() # 绑定chart一个x轴的刻度列表 """ 左Y轴 """ axis_y_left = QValueAxis() axis_y_left.setLabelsFont(font) axis_y_left.setLabelFormat('%i') chart.addAxis(axis_y_left, Qt.AlignLeft) # 图表加入左轴 """ 右Y轴 """ axis_y_right = QValueAxis() axis_y_right.setLabelsFont(font) axis_y_right.setLabelFormat('%.2f') chart.addAxis(axis_y_right, Qt.AlignRight) # 记录各轴的最值 x_bottom_min, x_bottom_max = 0, table_df.shape[0] y_left_min, y_left_max = 0, 0 y_right_min, y_right_max = 0, 0 """ 根据左轴画折线 """ for y_left_col in y_left_cols: # 根据左轴画折线 # 计算做轴的最值用于设置范围 table_df[y_left_col] = table_df[y_left_col].apply( covert_float) # y轴列转为浮点数值 # 获取最值 y_min, y_max = table_df[y_left_col].min(), table_df[y_left_col].max() if y_min < y_left_min: y_left_min = y_min if y_max > y_left_max: y_left_max = y_max # 取得图线的源数据作折线图 left_line_data = table_df.iloc[:, [x_bottom, y_left_col]] series = QLineSeries() series.setName(legend_labels[y_left_col]) for position_index, point_item in enumerate( left_line_data.values.tolist()): series.append(position_index, point_item[1]) # 取出源数据后一条线就2列数据 # 收集坐标标签 if not has_x_labels: chart.x_labels.append(point_item[0]) chart.addSeries(series) # 折线入图 series.attachAxis(axis_x_bottom) series.attachAxis(axis_y_left) # 左轴范围 axis_y_left.setRange(y_left_min, y_left_max) """ 根据右轴画折线 """ for y_right_col in y_right_cols: # 根据右轴画折线 # 计算做轴的最值用于设置范围 table_df[y_right_col] = table_df[y_right_col].apply( covert_float) # y轴列转为浮点数值 # 获取最值 y_min, y_max = table_df[y_right_col].min(), table_df[y_right_col].max() if y_min < y_right_min: y_right_min = y_min if y_max > y_right_max: y_right_max = y_max # 取得图线的源数据作折线图 left_line_data = table_df.iloc[:, [x_bottom, y_right_col]] series = QLineSeries() series.setName(legend_labels[y_right_col]) for position_index, point_item in enumerate( left_line_data.values.tolist()): series.append(position_index, point_item[1]) # 取出源数据后一条线就2列数据 chart.addSeries(series) series.attachAxis(axis_x_bottom) series.attachAxis(axis_y_right) # 右轴范围 axis_y_right.setRange(y_right_min, y_right_max) # 设置下轴刻度标签 # print('x轴最大值', x_bottom_max) x_bottom_interval = int(x_bottom_max / (tick_count - 1)) if x_bottom_interval == 0: for i in range(0, x_bottom_max): axis_x_bottom.append(chart.x_labels[i], i) else: for i in range(0, x_bottom_max, x_bottom_interval): axis_x_bottom.append(chart.x_labels[i], i) chart.legend().setAlignment(Qt.AlignBottom) return chart
def bars_stacked(name, table_df, x_bottom_cols, y_left_cols, y_right_cols, legend_labels, tick_count): """ 柱形堆叠图 :param name: 图表名称 :param table_df: 用于画图的pandas DataFrame对象 :param x_bottom_cols: 下轴列索引列表 :param y_left_cols: 左轴列索引列表 :param y_right_cols: 右轴列索引列表 :param legend_labels: 图例名称标签列表 :param tick_count: 横轴刻度标签数 :return: QChart实例 """ """ 过滤轴 """ for y_left_col in y_left_cols: if is_datetime64_any_dtype(table_df[y_left_col]): # 如果是时间轴 y_left_cols.remove(y_left_col) for y_right_col in y_right_cols: if is_datetime64_any_dtype(table_df[y_right_col]): # 如果是时间轴 y_right_cols.remove(y_right_col) # 将x轴转为字符串 x_bottom = x_bottom_cols[0] # x轴列 if is_datetime64_any_dtype(table_df[x_bottom]): # 如果x轴是时间轴 table_df[x_bottom] = table_df[x_bottom].apply( lambda x: x.strftime('%Y-%m-%d')) else: # x轴非时间轴 table_df[x_bottom] = table_df[x_bottom].apply(lambda x: str(x)) font = QFont() # 轴文字风格 font.setPointSize(7) # 轴标签文字大小 chart = QChart() # 图表实例 chart.layout().setContentsMargins(0, 0, 0, 0) # chart的外边距 chart.setMargins(QMargins(15, 5, 15, 0)) # chart内边距 chart.setTitle(name) # chart名称 """ x轴 """ axis_x_bottom = QCategoryAxis( chart, labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue) axis_x_bottom.setLabelsAngle(-90) # 逆时针旋转90度 axis_x_bottom.setLabelsFont(font) # 设置字体样式 axis_x_bottom.setGridLineVisible(False) # 竖向连接线不可见 # chart.addAxis(axis_x_bottom, Qt.AlignBottom) # 加入坐标x轴 has_x_labels = False # 收集x轴刻度的开关 chart.x_labels = list() # 绑定chart一个x轴的刻度列表 """ 左Y轴 """ axis_y_left = QValueAxis() axis_y_left.setLabelsFont(font) axis_y_left.setLabelFormat('%i') chart.addAxis(axis_y_left, Qt.AlignLeft) # 图表加入左轴 """ 右Y轴 """ axis_y_right = QValueAxis() axis_y_right.setLabelsFont(font) axis_y_right.setLabelFormat('%.2f') chart.addAxis(axis_y_right, Qt.AlignRight) # 记录各轴的最值 x_bottom_min, x_bottom_max = 0, table_df.shape[0] y_left_min, y_left_max = 0, 0 y_right_min, y_right_max = 0, 0 # 柱形图 left_bars = QBarSeries() """ 根据左轴画柱形 """ for y_left_col in y_left_cols: # 根据左轴画折线 # 计算做轴的最值用于设置范围 table_df[y_left_col] = table_df[y_left_col].apply( covert_float) # y轴列转为浮点数值 # 获取最值 y_min, y_max = table_df[y_left_col].min(), table_df[y_left_col].max() if y_min < y_left_min: y_left_min = y_min if y_max > y_left_max: y_left_max = y_max # 取得图表的源数据作柱形 left_bar_data = table_df.iloc[:, [x_bottom, y_left_col]] bar = QBarSet(legend_labels[y_left_col]) bar.setPen(QPen(Qt.transparent)) # 设置画笔轮廓线透明(数据量大会出现空白遮住柱形) for index, point_item in enumerate(left_bar_data.values.tolist()): bar.append(point_item[1]) if not has_x_labels: chart.x_labels.append(point_item[0]) has_x_labels = True # 关闭添加轴标签 left_bars.append(bar) # 柱形加入系列 left_bars.attachAxis(axis_y_left) # 左轴的范围 axis_y_left.setRange(y_left_min, y_left_max) """ 根据右轴画柱形 """ right_bars = QBarSeries() for y_right_col in y_right_cols: # 根据右轴画柱形 # 计算做轴的最值用于设置范围 table_df[y_right_col] = table_df[y_right_col].apply( covert_float) # y轴列转为浮点数值 # 获取最值 y_min, y_max = table_df[y_right_col].min(), table_df[y_right_col].max() if y_min < y_right_min: y_right_min = y_min if y_max > y_right_max: y_right_max = y_max # 取得图线的源数据作折线图 right_bar_data = table_df.iloc[:, [x_bottom, y_right_col]] bar = QBarSet(legend_labels[y_right_col]) bar.setPen(QPen(Qt.transparent)) for position_index, point_item in enumerate( right_bar_data.values.tolist()): bar.append(point_item[1]) # 取出源数据后一条线就2列数据 right_bars.append(bar) right_bars.attachAxis(axis_x_bottom) right_bars.attachAxis(axis_y_right) # 右轴范围 axis_y_right.setRange(y_right_min, y_right_max) chart.addSeries(left_bars) # 左轴的柱形图加入图表 # print(right_bars.count()) if right_bars.count() != 0: # 为空时加入会导致空位 chart.addSeries(right_bars) chart.setAxisX(axis_x_bottom, left_bars) # 关联设置x轴 # 横轴标签设置 x_bottom_interval = int(x_bottom_max / (tick_count - 1)) if x_bottom_interval == 0: for i in range(0, x_bottom_max): axis_x_bottom.append(chart.x_labels[i], i) else: for i in range(0, x_bottom_max, x_bottom_interval): axis_x_bottom.append(chart.x_labels[i], i) chart.legend().setAlignment(Qt.AlignBottom) return chart
def __init__(self, parent=None): super().__init__(parent=parent) self.setpoint_temperature = None self.chart = QChart() self.chart.legend().hide() self.setChart( self.chart ) self.setRenderHint(QPainter.Antialiasing) self.chart.setPlotAreaBackgroundBrush( QBrush(Qt.black) ) self.chart.setPlotAreaBackgroundVisible( True ) self.setpointTemperatureSeries = QLineSeries( self.chart ) pen = self.setpointTemperatureSeries.pen() pen.setWidthF(2.) pen.setColor( Qt.green ) self.setpointTemperatureSeries.setPen( pen ) #self.setpointTemperatureSeries.setUseOpenGL( True ) self.chart.addSeries( self.setpointTemperatureSeries ) self.temperatureSeries = QLineSeries( self.chart ) pen = self.temperatureSeries.pen() pen.setWidthF(2.) pen.setColor( Qt.red ) self.temperatureSeries.setPen( pen ) #self.temperatureSeries.setUseOpenGL( True ) self.chart.addSeries( self.temperatureSeries ) self.number_of_samples_to_keep = 2 * 5 * 60 self.xMin = QDateTime.currentDateTime().toMSecsSinceEpoch() self.xMax = QDateTime.currentDateTime().toMSecsSinceEpoch() self.yMin = 400 self.yMax = 0 #self.chart.createDefaultAxes() #x_axis = QValueAxis() x_axis = QDateTimeAxis() x_axis.setTitleText( "Time" ) x_axis.setFormat("HH:mm:ss") self.chart.addAxis( x_axis, Qt.AlignBottom ) self.temperatureSeries.attachAxis( x_axis ) self.setpointTemperatureSeries.attachAxis( x_axis ) startDate = QDateTime.currentDateTime().addSecs( -5 * 60 ) endDate = QDateTime.currentDateTime().addSecs( 5 * 60 ) #startDate = QDateTime(QDate(2017, 1, 9), QTime(17, 25, 0)) #endDate = QDateTime(QDate(2017, 1, 9), QTime(17, 50, 0)) #self.chart.axisX().setRange( startDate, endDate ) #self.chart.axisX().setRange( 0, 100 ) y_axis = QValueAxis() y_axis.setTitleText( "Temperature (K)" ) self.chart.addAxis( y_axis, Qt.AlignLeft ) self.temperatureSeries.attachAxis( y_axis ) self.setpointTemperatureSeries.attachAxis( y_axis ) self.chart.axisY().setRange( 0, 400 ) #self.chart.axisY().setRange( 260., 290. ) self.temperatureSeries.pointAdded.connect( self.Rescale_Axes ) #self.setpointTemperatureSeries.pointAdded.connect( self.Rescale_Axes ) self.setRubberBand( QChartView.HorizontalRubberBand ) # Customize chart title font = QFont() font.setPixelSize(24); self.chart.setTitleFont(font); self.chart.setTitleBrush(QBrush(Qt.white)); ## Customize chart background #backgroundGradient = QLinearGradient() #backgroundGradient.setStart(QPointF(0, 0)); #backgroundGradient.setFinalStop(QPointF(0, 1)); #backgroundGradient.setColorAt(0.0, QColor(0x000147)); #backgroundGradient.setColorAt(1.0, QColor(0x000117)); #backgroundGradient.setCoordinateMode(QGradient.ObjectBoundingMode); #self.chart.setBackgroundBrush(backgroundGradient); transparent_background = QBrush(QColor(0,0,0,0)) self.chart.setBackgroundBrush( transparent_background ) # Customize axis label font labelsFont = QFont() labelsFont.setPixelSize(16); x_axis.setLabelsFont(labelsFont) y_axis.setLabelsFont(labelsFont) x_axis.setTitleFont(labelsFont) y_axis.setTitleFont(labelsFont) # Customize axis colors axisPen = QPen(QColor(0xd18952)) axisPen.setWidth(2) x_axis.setLinePen(axisPen) y_axis.setLinePen(axisPen) # Customize axis label colors axisBrush = QBrush(Qt.white) x_axis.setLabelsBrush(axisBrush) y_axis.setLabelsBrush(axisBrush) x_axis.setTitleBrush(axisBrush) y_axis.setTitleBrush(axisBrush)
def create_piechart(self): series = QLineSeries() weights = SQLStatements.getallWeightChanges(self.userID) print(weights) weights = str(weights) weights = weights.replace("(", "") weights = weights.replace(")", "") weights = weights.replace(",", "") weights = weights.replace("[", "") weights = weights.replace("]", "") weightsTable = weights.split() print(weightsTable) count = 0 for x in weightsTable: x = int(float(x)) print(x) series.append(count, x) count = count + 2 chart = QChart() chart.addSeries(series) chart.setAnimationOptions(QChart.SeriesAnimations) chart.setTitle("Weight Change over time") chart.setTheme(QChart.ChartThemeBlueCerulean) chart.setBackgroundVisible(False) #Title Font size font = QFont("Sans Serif", ) font.setPixelSize(18) chart.setTitleFont(font) # X Axis Settings axisX = QValueAxis() axisX.setTitleText("Time") # Y Axis Settings axisY = QValueAxis() axisY.setTitleText("Weight (KG)") # Customize axis label font Lfont = QFont("Sans Serif") Lfont.setPixelSize(16) axisX.setLabelsFont(Lfont) axisY.setLabelsFont(Lfont) #add Axis chart.addAxis(axisX, Qt.AlignBottom) series.attachAxis(axisX) chart.addAxis(axisY, Qt.AlignLeft) series.attachAxis(axisY) chartview = QChartView(chart) chartview.setRenderHint(QPainter.Antialiasing) return chartview
class LastMonthsHistogram(QChartView): """ Chart that displays the balance from the whole portfolio from the last months """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.chart = QChart() def setupChartWithData(self): """ Chart gets updated displaying the new data. Data has to be expressed on a dictionary form: - keys are timestamps - values are total balance for that timestamp """ self.chart = QChart() self.chart.setTheme(QChart.ChartThemeDark) self.chart.setAnimationOptions(QChart.SeriesAnimations) self.chart.setBackgroundBrush(QBrush(QColor("transparent"))) # Series self.barseries = QBarSeries() currentyear, currentmonth = datetime.today().year, datetime.today( ).month dates, amounts = [], [] # Get 5 previous month numbers for _ in range(5): dates.append((currentmonth, currentyear)) currentmonth -= 1 if currentmonth == 0: currentmonth = 12 currentyear -= 1 # Get amounts for each month for d in dates: month, year = d amounts.append( dbhandler.get_total_wealth_on_month(month, year=year)) # Iterate months and amount and insert them into the histogram appropiately barset = QBarSet('Total wealth') labelsfont = QFont() labelsfont.setFamily('Inter') labelsfont.setBold(True) barset.setLabelFont(labelsfont) barset.setColor(QColor("#D3EABD")) x_values = [] for d, a in zip(reversed(dates), reversed(amounts)): if a > 0: barset.append(int(a)) x_values.append(calendar.month_name[d[0]]) self.barseries.append(barset) self.barseries.setName("Last Months") self.barseries.setLabelsVisible(True) self.barseries.setBarWidth(0.2) self.barseries.setLabelsPosition(QAbstractBarSeries.LabelsOutsideEnd) self.chart.addSeries(self.barseries) # Axis X (Dates) self.x_axis = QBarCategoryAxis() self.x_axis.setTitleText(self.tr('Date')) labelsfont = QFont() labelsfont.setFamily('Roboto') labelsfont.setLetterSpacing(QFont.AbsoluteSpacing, 1) labelsfont.setWeight(QFont.Light) labelsfont.setPointSize(9) self.x_axis.setLabelsFont(labelsfont) self.x_axis.setGridLineVisible(False) self.x_axis.setLineVisible(False) self.x_axis.setLinePenColor(QColor("#D3EABD")) self.x_axis.setTitleVisible(False) self.x_axis.append(x_values) self.chart.addAxis(self.x_axis, Qt.AlignBottom) # Axis Y (Balances) self.y_axis = QValueAxis() self.y_axis.setMax(max(amounts) * 1.3) self.y_axis.setMin(min(amounts) * 0.95) self.y_axis.hide() labelsfont = QFont() labelsfont.setPointSize(4) self.y_axis.setLabelsFont(labelsfont) self.chart.addAxis(self.y_axis, Qt.AlignLeft) # Attach axis to series self.barseries.attachAxis(self.x_axis) self.barseries.attachAxis(self.y_axis) # Legend self.chart.legend().hide() # Set up chart on ChartView self.setChart(self.chart) self.setRenderHint(QPainter.Antialiasing) self.setStyleSheet("border: 0px; background-color: rgba(0,0,0,0)")