def __init__(self, bargraph): super(GraphModifier, self).__init__() self.m_graph = bargraph self.m_xRotation = 0.0 self.m_yRotation = 0.0 self.m_fontSize = 30 self.m_segments = 4 self.m_subSegments = 3 self.m_minval = -20.0 self.m_maxval = 20.0 self.m_temperatureAxis = QValue3DAxis() self.m_yearAxis = QCategory3DAxis() self.m_monthAxis = QCategory3DAxis() self.m_primarySeries = QBar3DSeries() self.m_secondarySeries = QBar3DSeries() self.m_barMesh = QAbstract3DSeries.MeshBevelBar self.m_smooth = False self.m_graph.setShadowQuality(QAbstract3DGraph.ShadowQualitySoftMedium) self.m_graph.activeTheme().setBackgroundEnabled(False) self.m_graph.activeTheme().setFont( QFont('Times New Roman', self.m_fontSize)) self.m_graph.activeTheme().setLabelBackgroundEnabled(True) self.m_graph.setMultiSeriesUniform(True) self.m_temperatureAxis.setTitle("Average temperature") self.m_temperatureAxis.setSegmentCount(self.m_segments) self.m_temperatureAxis.setSubSegmentCount(self.m_subSegments) self.m_temperatureAxis.setRange(self.m_minval, self.m_maxval) self.m_temperatureAxis.setLabelFormat(u"%.1f \N{degree sign}C") self.m_yearAxis.setTitle("Year") self.m_monthAxis.setTitle("Month") self.m_graph.setValueAxis(self.m_temperatureAxis) self.m_graph.setRowAxis(self.m_yearAxis) self.m_graph.setColumnAxis(self.m_monthAxis) self.m_primarySeries.setItemLabelFormat( "Oulu - @colLabel @rowLabel: @valueLabel") self.m_primarySeries.setMesh(QAbstract3DSeries.MeshBevelBar) self.m_primarySeries.setMeshSmooth(False) self.m_secondarySeries.setItemLabelFormat( "Helsinki - @colLabel @rowLabel: @valueLabel") self.m_secondarySeries.setMesh(QAbstract3DSeries.MeshBevelBar) self.m_secondarySeries.setMeshSmooth(False) self.m_secondarySeries.setVisible(False) self.m_graph.addSeries(self.m_primarySeries) self.m_graph.addSeries(self.m_secondarySeries) self.m_preset = Q3DCamera.CameraPresetFront self.changePresetCamera() self.resetTemperatureData()
def setupGraph(self): """Load data and set up the window for the bar graph.""" header_label = QLabel( "Average Monthly Temperatures in Reykjavík, Iceland 1990-2000 (˚C)" ) header_label.setAlignment(Qt.AlignCenter) # Load the data about average temperatures in Reykjavík from the CSV file temperature_data = self.loadCSVFile() # Select 11 sample years: 1990-2000. Don't select the first and last columns rows, columns = temperature_data.shape years = temperature_data[rows - 11:rows, 1] monthly_temps = temperature_data[rows - 11:rows, 2:columns - 1].astype(float) bar_graph = Q3DBars() # Create instance for bar graph bar_graph.scene().activeCamera().setCameraPreset( Q3DCamera.CameraPresetFront) # Create a list of QBarDataItem objects data_items = [] for row in monthly_temps: data_items.append([QBarDataItem(value) for value in row]) months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ] # Create instance of QBar3DSeries, change the base color and color of # selected items, and add data and labels to the series series = QBar3DSeries() series.setBaseColor(QColor("#17A4D9")) series.setSingleHighlightColor(QColor("#F8A307")) series.dataProxy().addRows(data_items) series.dataProxy().setRowLabels(years) # rowLabel series.dataProxy().setColumnLabels(months) # colLabel # Create the valueLabel. Use QValue3dAxis so we can format the axis's label temperature_axis = QValue3DAxis() temperature_axis.setRange(-10, 20) temperature_axis.setLabelFormat(u"%.1f \N{degree sign}C") bar_graph.setValueAxis(temperature_axis) # When items in the graph are selected, a label appears overhead with information # about that item. Set the format of information in the label series.setItemLabelFormat( "Reykjavík - @colLabel @rowLabel: @valueLabel") bar_graph.addSeries(series) # Add the series to the bar graph # 3D graph classes inherit QWindow, so we must use createWindowContainer() to # create a holder for the 3D graph in our window since they can't be used # as a normal widget container = self.createWindowContainer(bar_graph) v_box = QVBoxLayout() v_box.addWidget(header_label) v_box.addWidget(container, 1) self.setLayout(v_box)
def __init__(self, rainfall): super(RainfallGraph, self).__init__() self.m_graph = rainfall self.m_mapping = None self.m_dataSet = None # In the data file the months are in numeric format, so create a custom # list. self.m_numericMonths = [str(m) for m in range(1, 12 + 1)] self.m_columnCount = len(self.m_numericMonths) self.m_years = [str(y) for y in range(2000, 2012 + 1)] self.m_rowCount = len(self.m_years) self.m_proxy = VariantBarDataProxy() series = QBar3DSeries(self.m_proxy) series.setMesh(QAbstract3DSeries.MeshCylinder) self.m_graph.addSeries(series) self.m_graph.setBarThickness(1.0) self.m_graph.setBarSpacing(QSizeF(0.2, 0.2)) self.m_graph.rowAxis().setTitle("Year") self.m_graph.columnAxis().setTitle("Month") self.m_graph.valueAxis().setTitle("rainfall") self.m_graph.valueAxis().setLabelFormat("%d mm") self.m_graph.valueAxis().setSegmentCount(5) self.m_graph.rowAxis().setLabels(self.m_years) self.m_graph.columnAxis().setLabels(self.months) self.m_graph.setShadowQuality(QAbstract3DGraph.ShadowQualityMedium) self.m_graph.setSelectionMode(QAbstract3DGraph.SelectionItemAndColumn | QAbstract3DGraph.SelectionSlice) self.m_graph.activeTheme().setType(Q3DTheme.ThemeArmyBlue) self.m_graph.activeTheme().setFont(QFont('Century Gothic', 30)) self.m_graph.activeTheme().setLabelBackgroundEnabled(False) self.m_graph.scene().activeCamera().setCameraPreset( Q3DCamera.CameraPresetIsometricRightHigh) self.m_graph.setTitle("Monthly rainfall in Northern Finland")
def __init__(self, bargraph): super(GraphModifier, self).__init__() self.m_graph = bargraph # Q3DBars 实例 self.m_xRotation = 0.0 # 水平旋转角度 self.m_yRotation = 0.0 # 垂直旋转角度 self.m_fontSize = 30 self.m_segments = 4 self.m_subSegments = 3 self.m_minval = -20.0 self.m_maxval = 20.0 self.m_temperatureAxis = QValue3DAxis() # 温度轴 self.m_yearAxis = QCategory3DAxis() # 年份轴 self.m_monthAxis = QCategory3DAxis() # 月份轴 self.m_primarySeries = QBar3DSeries() # 主序列 self.m_secondarySeries = QBar3DSeries() # 次序列 self.m_barMesh = QAbstract3DSeries.MeshBevelBar # 预定义的网格类型 self.m_smooth = False # 是否平滑 # 阴影以柔化的边缘高质量渲染 self.m_graph.setShadowQuality(QAbstract3DGraph.ShadowQualitySoftMedium) # 当前主题Q3DTheme设置背景是否可见 self.m_graph.activeTheme().setBackgroundEnabled(False) # 当前主题Q3DTheme设置字体 self.m_graph.activeTheme().setFont( QFont('Times New Roman', self.m_fontSize)) # 当前主题Q3DTheme设置标签是使用彩色背景还是使用完全透明的背景绘制 self.m_graph.activeTheme().setLabelBackgroundEnabled(True) # 是否按比例将比例尺设置为单个系列比例尺来缩放比例 self.m_graph.setMultiSeriesUniform(True) self.m_temperatureAxis.setTitle( Tr.get("Average temperature", "Average temperature")) # 轴上的段数。这表明绘制了多少标签。要绘制的网格线的数量使用公式计算:segments * subsegments + 1。预设默认值为5。该值不能低于1 self.m_temperatureAxis.setSegmentCount(self.m_segments) # 轴上每个段内的子段数。 # 除每个线段外,还在每个子线段之间绘制网格线。预设默认值为1。该值不能低于1。 self.m_temperatureAxis.setSubSegmentCount(self.m_subSegments) self.m_temperatureAxis.setRange(self.m_minval, self.m_maxval) self.m_temperatureAxis.setLabelFormat(u"%.1f \N{degree sign}C") self.m_yearAxis.setTitle("Year") self.m_monthAxis.setTitle("Month") self.m_graph.setValueAxis(self.m_temperatureAxis) # 设置活动行的轴为年份 self.m_graph.setRowAxis(self.m_yearAxis) # 设置活动列的轴为月份 self.m_graph.setColumnAxis(self.m_monthAxis) self.m_primarySeries.setItemLabelFormat( "Oulu - @colLabel @rowLabel: @valueLabel") # 设置网格类型 self.m_primarySeries.setMesh(QAbstract3DSeries.MeshBevelBar) self.m_primarySeries.setMeshSmooth(False) self.m_secondarySeries.setItemLabelFormat( "Helsinki - @colLabel @rowLabel: @valueLabel") self.m_secondarySeries.setMesh(QAbstract3DSeries.MeshBevelBar) self.m_secondarySeries.setMeshSmooth(False) self.m_secondarySeries.setVisible(False) self.m_graph.addSeries(self.m_primarySeries) self.m_graph.addSeries(self.m_secondarySeries) self.m_preset = Q3DCamera.CameraPresetFront self.changePresetCamera() self.resetTemperatureData()
def setupWindow(self): """The window is comprised of two main parts: A Q3DBars graph on the left, and QToolBox on the right containing different widgets for tweaking different settings in the Q3DBars graph.""" header_label = QLabel( "Comparison of Average Monthly Temperatures of Select U.S. Cities 1990-2000 (˚C)" ) header_label.setAlignment(Qt.AlignCenter) # Load and prepare the data for the three datasets data_files = [ "LasVegas_temp.csv", "Spokane_temp.csv", "Richmond_temp.csv" ] temperature_data = {} # Create a dictionary with key, value pairs pertaining to each city and dataset for f in data_files: data_name = f.split( "_")[0] + "_data" # Create a dictionary key for each city data = self.loadCSVFile("files/" + f) # Select 11 years: 1990-2000; the first column in each file is the years rows, columns = data.shape self.years = data[:, 0] monthly_temps = data[:, 1:columns].astype(float) temperature_data[data_name] = monthly_temps bar_graph = Q3DBars() # Create instance for bar graph bar_graph.setMultiSeriesUniform( True) # Bars are scaled proportionately bar_graph.scene().activeCamera().setCameraPreset( Q3DCamera.CameraPresetFront) # Create lists of QBarDataItem objects for each city vegas_data_items = [] for row in temperature_data["LasVegas_data"]: vegas_data_items.append([QBarDataItem(value) for value in row]) spokane_data_items = [] for row in temperature_data["Spokane_data"]: spokane_data_items.append([QBarDataItem(value) for value in row]) richmond_data_items = [] for row in temperature_data["Richmond_data"]: richmond_data_items.append([QBarDataItem(value) for value in row]) self.months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ] # Create instances of QBar3DSeries for each set of data; dataProxy() handles # modifying data in the series vegas_series = QBar3DSeries() vegas_series.dataProxy().addRows(vegas_data_items) vegas_series.dataProxy().setRowLabels(self.years) # rowLabel vegas_series.dataProxy().setColumnLabels(self.months) # colLabel spokane_series = QBar3DSeries() spokane_series.dataProxy().addRows(spokane_data_items) richmond_series = QBar3DSeries() richmond_series.dataProxy().addRows(richmond_data_items) # Create the valueLabel temperature_axis = QValue3DAxis() temperature_axis.setRange(-10, 40) temperature_axis.setLabelFormat(u"%.1f \N{degree sign}C") bar_graph.setValueAxis(temperature_axis) # Set the format for the labels that appear when items are clicked on vegas_series.setItemLabelFormat( "LasVegas - @colLabel @rowLabel: @valueLabel") spokane_series.setItemLabelFormat( "Spokane - @colLabel @rowLabel: @valueLabel") richmond_series.setItemLabelFormat( "Richmond - @colLabel @rowLabel: @valueLabel") # Add the three series to the bar graph bar_graph.setPrimarySeries(vegas_series) bar_graph.addSeries(spokane_series) bar_graph.addSeries(richmond_series) # Create a QWidget to hold only the graph graph_container = QWidget.createWindowContainer(bar_graph) main_h_box = QHBoxLayout() # Main layout for the entire window graph_v_box = QVBoxLayout() # Layout that holds the graph graph_v_box.addWidget(header_label) graph_v_box.addWidget(graph_container, 1) ############################################################################## # The following section creates the QToolBox that appears on the # right of the window and contains widgets for interacting with the graph self.modifier = GraphModifier(self, bar_graph) # Create modifier instance settings_toolbox = QToolBox() settings_toolbox.setFixedWidth(300) settings_toolbox.setCurrentIndex(0) # Show the first tab # The first tab - Widgets for rotating the bar graph and changing the camera horizontal_rotation_slider = QSlider(Qt.Horizontal) horizontal_rotation_slider.setTickInterval(20) horizontal_rotation_slider.setRange(-180, 180) horizontal_rotation_slider.setValue(0) horizontal_rotation_slider.setTickPosition(QSlider.TicksBelow) horizontal_rotation_slider.valueChanged.connect( self.modifier.rotateHorizontal) vertical_rotation_slider = QSlider(Qt.Horizontal) vertical_rotation_slider.setTickInterval(20) vertical_rotation_slider.setRange(-180, 180) vertical_rotation_slider.setValue(0) vertical_rotation_slider.setTickPosition(QSlider.TicksBelow) vertical_rotation_slider.valueChanged.connect( self.modifier.rotateVertical) # QPushButton for changing the camera's view point camera_view_button = QPushButton("Change Camera View") camera_view_button.clicked.connect(self.modifier.changeCameraView) # Layout for the View tab (first tab) view_tab_container = QWidget() view_tab_v_box = QVBoxLayout() view_tab_v_box.setAlignment(Qt.AlignTop) view_tab_v_box.addWidget(QLabel("Rotate Horizontally")) view_tab_v_box.addWidget(horizontal_rotation_slider) view_tab_v_box.addWidget(QLabel("Rotate Vertically")) view_tab_v_box.addWidget(vertical_rotation_slider) view_tab_v_box.addWidget(camera_view_button) view_tab_container.setLayout(view_tab_v_box) settings_toolbox.addItem(view_tab_container, "View") # The second tab - Widgets for changing the appearance of the graph. Recheck the # background and grid checkboxes if the theme has changed show_background_cb = QCheckBox("Show Background") show_background_cb.setChecked(True) show_background_cb.stateChanged.connect( self.modifier.showOrHideBackground) self.modifier.background_selected.connect( show_background_cb.setChecked) show_grid_cb = QCheckBox("Show Grid") show_grid_cb.setChecked(True) show_grid_cb.stateChanged.connect(self.modifier.showOrHideGrid) self.modifier.grid_selected.connect(show_grid_cb.setChecked) smooth_bars_cb = QCheckBox("Smoothen Bars") smooth_bars_cb.stateChanged.connect(self.modifier.smoothenBars) # QComboBox for selecting the Qt theme themes = [ "Qt", "Primary Colors", "Digia", "Stone Moss", "Army Blue", "Retro", "Ebony", "Isabelle" ] select_theme_combo = QComboBox() select_theme_combo.addItems(themes) select_theme_combo.setCurrentIndex(0) select_theme_combo.currentIndexChanged.connect( self.modifier.changeTheme) # QComboBox for selecting the visual style of the bars bar_style_combo = QComboBox() bar_style_combo.addItem("Bar", QAbstract3DSeries.MeshBar) bar_style_combo.addItem("Pyramid", QAbstract3DSeries.MeshPyramid) bar_style_combo.addItem("Cylinder", QAbstract3DSeries.MeshCylinder) bar_style_combo.addItem("Sphere", QAbstract3DSeries.MeshSphere) bar_style_combo.setCurrentIndex(0) bar_style_combo.currentIndexChanged.connect( self.modifier.changeBarStyle) # Layout for the Style tab (second tab) style_tab_container = QWidget() style_tab_v_box = QVBoxLayout() style_tab_v_box.setAlignment(Qt.AlignTop) style_tab_v_box.addWidget(show_background_cb) style_tab_v_box.addWidget(show_grid_cb) style_tab_v_box.addWidget(smooth_bars_cb) style_tab_v_box.addWidget(QLabel("Select Qt Theme")) style_tab_v_box.addWidget(select_theme_combo) style_tab_v_box.addWidget(QLabel("Select Bar Style")) style_tab_v_box.addWidget(bar_style_combo) style_tab_container.setLayout(style_tab_v_box) settings_toolbox.addItem(style_tab_container, "Style") # The third tab - Widgets for hiding/showing different series and changing how # items are viewed and selected second_series_cb = QCheckBox("Show Second Series") second_series_cb.setChecked(True) second_series_cb.stateChanged.connect(self.modifier.showOrHideSeries) third_series_cb = QCheckBox("Show Third Series") third_series_cb.setChecked(True) third_series_cb.stateChanged.connect(self.modifier.showOrHideSeries) # QComboBox for changing how items in the bar graph are selected selection_mode_combo = QComboBox() selection_mode_combo.addItem("None", QAbstract3DGraph.SelectionNone) selection_mode_combo.addItem("Bar", QAbstract3DGraph.SelectionItem) selection_mode_combo.addItem("Row", QAbstract3DGraph.SelectionRow) selection_mode_combo.addItem("Column", QAbstract3DGraph.SelectionColumn) selection_mode_combo.addItem( "Item, Row, Column", QAbstract3DGraph.SelectionItemRowAndColumn) selection_mode_combo.setCurrentIndex(1) selection_mode_combo.currentIndexChanged.connect( self.modifier.changeSelectionStyle) # QComboBox for selecting which years to view select_year_combo = QComboBox() select_year_combo.addItems(self.years) select_year_combo.addItem("All Years") select_year_combo.setCurrentIndex(len(self.years)) select_year_combo.currentIndexChanged.connect( self.modifier.selectYears) # QComboBox for selecting which months to view select_month_combo = QComboBox() select_month_combo.addItems(self.months) select_month_combo.addItem("All Months") select_month_combo.setCurrentIndex(len(self.months)) select_month_combo.currentIndexChanged.connect( self.modifier.selectMonths) # Layout for the Selection tab (third tab) selection_tab_container = QWidget() selection_tab_v_box = QVBoxLayout() selection_tab_v_box.addWidget(second_series_cb) selection_tab_v_box.addWidget(third_series_cb) selection_tab_v_box.addWidget(QLabel("Choose Selection Mode")) selection_tab_v_box.addWidget(selection_mode_combo) selection_tab_v_box.addWidget(QLabel("Select Year")) selection_tab_v_box.addWidget(select_year_combo) selection_tab_v_box.addWidget(QLabel("Select Month")) selection_tab_v_box.addWidget(select_month_combo) selection_tab_container.setLayout(selection_tab_v_box) settings_toolbox.addItem(selection_tab_container, "Selection") # Set up the layout for the settings toolbox settings_v_box = QVBoxLayout() settings_v_box.addWidget(settings_toolbox, 0, Qt.AlignTop) main_h_box.addLayout(graph_v_box) main_h_box.addLayout(settings_v_box) main_widget = QWidget() main_widget.setLayout(main_h_box) self.setCentralWidget(main_widget)
container.setFocusPolicy(Qt.StrongFocus) widget = QWidget() layout = QVBoxLayout(widget) tableWidget = QTableWidget() layout.addWidget(container, 1) layout.addWidget(tableWidget, 1, Qt.AlignHCenter) tableWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) tableWidget.setAlternatingRowColors(True) widget.setWindowTitle("Hours spent on the Internet") # Since we are dealing with QTableWidget, the model will already have data # sorted properly into rows and columns, so we simply set the # useModelCategories property to True to utilise this. proxy = QItemModelBarDataProxy(tableWidget.model()) proxy.setUseModelCategories(True) series = QBar3DSeries(proxy) series.setMesh(QAbstract3DSeries.MeshPyramid) graph.addSeries(series) generator = GraphDataGenerator(graph, tableWidget) series.selectedBarChanged.connect(generator.selectFromTable) tableWidget.currentCellChanged.connect(generator.selectedFromTable) widget.show() generator.start() sys.exit(app.exec_())