MatPlotLib PyQt5 Layout Problems - matplotlib

MatPlotLib PyQt5 Layout Problems:
Using horizontal and vertical layouts, it seems to be very difficult to get the widgets where I want them. Maybe there is another way of doing it, for instance:
If one can put the canvas and toolbar in a container or some kind of widget. Then you can size it and put it where you want.
If one can limit the size of the plot so that the UI in the background is visible. This seems impossible though.
What about using QGridLayout?
I have tried many things, but am very confused and nothing seems to work.
The problems I have (using the current horizontal and vertical layouts) are:
The labels drift and are not aligned with the widgets.
The buttonbox is too wide. Can the buttons be split between the last two columns?
Here is some code. Sorry for the formatting. (It's hard to get the 4 spaces right):
import sys
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt
import random
from PyQt5.QtWidgets import QPushButton, QVBoxLayout, QHBoxLayout, QApplication, QDialog, QGridLayout, QLayout
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(QDialog):
def __init__(self, parent=None):
super(Ui_Dialog, self).__init__(parent)
self.setupUi(self)
self.setupPlot()
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(719, 353)
Dialog.setWindowTitle("Task")
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setGeometry(QtCore.QRect(590, 310, 121, 32))
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.label1 = QtWidgets.QLabel(Dialog)
self.label1.setGeometry(QtCore.QRect(590, 40, 51, 16))
self.label1.setText("label1:")
self.label1.setObjectName("label1")
self.label2 = QtWidgets.QLabel(Dialog)
self.label2.setGeometry(QtCore.QRect(590, 70, 41, 16))
self.label2.setText("label2:")
self.label2.setObjectName("label2")
self.cBox1 = QtWidgets.QComboBox(Dialog)
self.cBox1.setGeometry(QtCore.QRect(650, 40, 61, 22))
self.cBox1.setLayoutDirection(QtCore.Qt.LeftToRight)
self.cBox1.setEditable(False)
self.cBox1.setCurrentText("Option0")
self.cBox1.setMaxVisibleItems(2)
self.cBox1.setObjectName("cBox1")
self.cBox1.addItem("")
self.cBox1.setItemText(0, "Option0")
self.cBox1.addItem("")
self.cBox1.setItemText(1, "Option1")
self.label5 = QtWidgets.QLabel(Dialog)
self.label5.setGeometry(QtCore.QRect(590, 160, 51, 16))
self.label5.setText("label5:")
self.label5.setObjectName("label5")
self.dSpinBox5 = QtWidgets.QDoubleSpinBox(Dialog)
self.dSpinBox5.setGeometry(QtCore.QRect(650, 160, 62, 22))
self.dSpinBox5.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.dSpinBox5.setMaximum(1999.99)
self.dSpinBox5.setObjectName("dSpinBox5")
self.dSpinBox4 = QtWidgets.QDoubleSpinBox(Dialog)
self.dSpinBox4.setGeometry(QtCore.QRect(650, 130, 62, 22))
self.dSpinBox4.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.dSpinBox4.setMaximum(1999.99)
self.dSpinBox4.setObjectName("dSpinBox4")
self.label0 = QtWidgets.QLabel(Dialog)
self.label0.setGeometry(QtCore.QRect(590, 10, 41, 16))
self.label0.setText("label0:")
self.label0.setObjectName("label0")
self.dSpinBox3 = QtWidgets.QDoubleSpinBox(Dialog)
self.dSpinBox3.setGeometry(QtCore.QRect(650, 100, 62, 22))
self.dSpinBox3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.dSpinBox3.setMaximum(1999.99)
self.dSpinBox3.setObjectName("dSpinBox3")
self.label3 = QtWidgets.QLabel(Dialog)
self.label3.setGeometry(QtCore.QRect(590, 100, 61, 16))
self.label3.setText("label3:")
self.label3.setObjectName("label3")
self.lineEdit0 = QtWidgets.QLineEdit(Dialog)
self.lineEdit0.setGeometry(QtCore.QRect(650, 10, 61, 20))
self.lineEdit0.setInputMask("")
self.lineEdit0.setText("")
self.lineEdit0.setObjectName("lineEdit0")
self.label4 = QtWidgets.QLabel(Dialog)
self.label4.setGeometry(QtCore.QRect(590, 130, 41, 16))
self.label4.setText("label4:")
self.label4.setObjectName("label4")
self.spinBox2 = QtWidgets.QSpinBox(Dialog)
self.spinBox2.setGeometry(QtCore.QRect(650, 70, 61, 22))
self.spinBox2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.spinBox2.setMaximum(999)
self.spinBox2.setSingleStep(10)
self.spinBox2.setProperty("value", 50)
self.spinBox2.setObjectName("spinBox2")
self.label6 = QtWidgets.QLabel(Dialog)
self.label6.setGeometry(QtCore.QRect(590, 190, 41, 16))
self.label6.setText("label6:")
self.label6.setObjectName("label6")
self.dSpinBox6 = QtWidgets.QDoubleSpinBox(Dialog)
self.dSpinBox6.setGeometry(QtCore.QRect(650, 190, 62, 22))
self.dSpinBox6.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.dSpinBox6.setReadOnly(True)
self.dSpinBox6.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
self.dSpinBox6.setObjectName("dSpinBox6")
self.label7 = QtWidgets.QLabel(Dialog)
self.label7.setGeometry(QtCore.QRect(590, 220, 47, 16))
self.label7.setText("label7:")
self.label7.setObjectName("label7")
self.spinBox7 = QtWidgets.QSpinBox(Dialog)
self.spinBox7.setGeometry(QtCore.QRect(650, 220, 61, 22))
self.spinBox7.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.spinBox7.setMaximum(999)
self.spinBox7.setProperty("value", 50)
self.spinBox7.setObjectName("spinBox7")
self.checkBox8 = QtWidgets.QCheckBox(Dialog)
self.checkBox8.setGeometry(QtCore.QRect(650, 250, 61, 20))
self.checkBox8.setLayoutDirection(QtCore.Qt.RightToLeft)
self.checkBox8.setText("")
self.checkBox8.setCheckable(False)
self.checkBox8.setObjectName("checkBox8")
self.checkBox9 = QtWidgets.QCheckBox(Dialog)
self.checkBox9.setGeometry(QtCore.QRect(650, 280, 61, 20))
self.checkBox9.setLayoutDirection(QtCore.Qt.RightToLeft)
self.checkBox9.setText("")
self.checkBox9.setCheckable(False)
self.checkBox9.setObjectName("checkBox9")
self.label8 = QtWidgets.QLabel(Dialog)
self.label8.setGeometry(QtCore.QRect(590, 250, 51, 16))
self.label8.setText("label8")
self.label8.setObjectName("label8")
self.label9 = QtWidgets.QLabel(Dialog)
self.label9.setGeometry(QtCore.QRect(590, 276, 47, 16))
self.label9.setText("label9")
self.label9.setObjectName("label9")
self.buttonBox.accepted.connect(Dialog.accept)
self.buttonBox.rejected.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def setupPlot(self):
self.setLayout(QHBoxLayout())
self.layout().setContentsMargins(0, 0, 0, 0)
self.figure = plt.figure()
self.figure.set_facecolor("none")
self.canvas = FigureCanvas(self.figure)
self.toolbar = NavigationToolbar(self.canvas, self)
self.widget = QtWidgets.QWidget()
layout = QVBoxLayout()
self.widget.setLayout(layout)
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
self.layout().addWidget(self.widget)
self.widget = QtWidgets.QWidget()
layout = QVBoxLayout()
self.widget.setLayout(layout)
layout.addWidget(self.label0)
layout.addWidget(self.label1)
layout.addWidget(self.label2)
layout.addWidget(self.label3)
layout.addWidget(self.label4)
layout.addWidget(self.label5)
layout.addWidget(self.label6)
layout.addWidget(self.label7)
layout.addWidget(self.label8)
layout.addWidget(self.label9)
self.layout().addWidget(self.widget)
self.widget = QtWidgets.QWidget()
layout = QVBoxLayout()
self.widget.setLayout(layout)
layout.addWidget(self.lineEdit0)
layout.addWidget(self.cBox1)
layout.addWidget(self.spinBox2)
layout.addWidget(self.dSpinBox3)
layout.addWidget(self.dSpinBox4)
layout.addWidget(self.dSpinBox5)
layout.addWidget(self.dSpinBox6)
layout.addWidget(self.spinBox7)
layout.addWidget(self.checkBox8)
layout.addWidget(self.checkBox9)
layout.addWidget(self.buttonBox)
self.layout().addWidget(self.widget)
self.plot()
def plot(self):
data = [random.random() for i in range(10)]
self.figure.clear()
ax = self.figure.add_subplot(111)
ax.plot(data, '*-')
self.canvas.draw()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Ui_Dialog()
main.show()
sys.exit(app.exec_())

#ImportanceOfBeingErnest Your comment is what solved the question. Appreciated:
Removed all the setGeometry calls.
Created a QGridLayout .
Added widgets to the gridLayout like this:
self.layout().addWidget(self.checkBoxDone, 3, 4, 1, 1)
NB: Be careful not to confuse the parameters:
widget
start row (from 0 at the top)
start column (from 0 on the left)
number of rows to span (downwards)
number of columns to span (to the right)

Related

Widget background not showing PyQt6

I created a registration widget in qt designer.I am importing the second file into the first one. When I run the code instead of my background is a white window. And there should be a picture that is in the repository. Although the link to the background itself is present
main.py
import sys
from PyQt6.QtWidgets import QApplication, QDialog,QFileDialog
from PyQt6 import QtWidgets
from ui_imagedialog import Ui_ImageDialog
from AboutTheProgram import Ui_AboutTheProgram
class MainWindows(QDialog,Ui_ImageDialog):
def __init__(self):
super().__init__()
self.MainMenu = Ui_ImageDialog
self.setupUi(self)
self.pushLogin.clicked.connect(self.TransitionAboutTheProgram)
# При нажатии на кнопку login перейти на новую страницу
def TransitionAboutTheProgram(self):
abouttheprogram=AboutTheProgram()
window.addWidget(abouttheprogram)
window.setCurrentIndex(window.currentIndex()+1)
class AboutTheProgram(QDialog,Ui_AboutTheProgram):
def __init__(self):
super().__init__()
self.abouttheprogram = Ui_AboutTheProgram
self.setupUi(self)
app = QApplication(sys.argv)
window = QtWidgets.QStackedWidget()
mainwindow=MainWindows()
window.addWidget(mainwindow)
window.show()
sys.exit(app.exec())
ul_imagedialog.py
from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_ImageDialog(object):
def setupUi(self, ImageDialog):
ImageDialog.setObjectName("ImageDialog")
ImageDialog.resize(445, 514)
self.widget = QtWidgets.QWidget(parent=ImageDialog)
self.widget.setGeometry(QtCore.QRect(10, 10, 370, 480))
self.widget.setStyleSheet("QPushButton#pushLogin{\n"
" background-color:qlineargradient(spread:pad, x1:0, y1:0.505682, x2:1, y2:0.477, stop:0 rgba(20, 47, 78, 219), stop:1 rgba(85, 98, 112, 226));\n"
" color:rgba(255,255,255,210);\n"
" border_radius:5px;\n"
"}\n"
"QPushButton#pushLogin:hover{\n"
" background-color:qlineargradient(spread:pad, x1:0, y1:0.505682, x2:1, y2:0.477, stop:0 rgba(40, 67, 98, 219), stop:1 rgba(105, 118, 132, 226));\n"
"}\n"
"QPushButton#pushLogin:pressed{\n"
" padding-left:5px;\n"
" padding-top:5px;\n"
" background-color:rgba(105,118,132,200);\n"
"}\n"
"QPushButton#pushUrlDiscord{\n"
" background-color:rgba(0,0,0,0);\n"
" color:rgba(85,98,112,255);\n"
"}\n"
"QPushButton#pushUrlDiscord:hover{\n"
" color:rgba(155,168,182,220);\n"
"}\n"
"QPushButton#pushUrlDiscord:pressed{\n"
" padding-left:5px;\n"
" padding-top:5px;\n"
" color:rgba(115,128,142,255)\n"
"}\n"
"QPushButton#pushUrlGitHub{\n"
" background-color:rgba(0,0,0,0);\n"
" color:rgba(85,98,112,255);\n"
"}\n"
"QPushButton#pushUrlGitHub:hover{\n"
" color:rgba(155,168,182,220);\n"
"}\n"
"QPushButton#pushUrlGitHub:pressed{\n"
" padding-left:5px;\n"
" padding-top:5px;\n"
" color:rgba(115,128,142,255)\n"
"}\n"
"QPushButton#pushUrlFacebook{\n"
" background-color:rgba(0,0,0,0);\n"
" color:rgba(85,98,112,255);\n"
"}\n"
"QPushButton#pushUrlFacebook:hover{\n"
" color:rgba(155,168,182,220);\n"
"}\n"
"QPushButton#pushUrlFacebook:pressed{\n"
" padding-left:5px;\n"
" padding-top:5px;\n"
" color:rgba(115,128,142,255)\n"
"}\n"
"QPushButton#pushUrlYouTube{\n"
" background-color:rgba(0,0,0,0);\n"
" color:rgba(85,98,112,255);\n"
"}\n"
"QPushButton#pushUrlYouTube:hover{\n"
" color:rgba(155,168,182,220);\n"
"}\n"
"QPushButton#pushUrlYouTubek:pressed{\n"
" padding-left:5px;\n"
" padding-top:5px;\n"
" color:rgba(115,128,142,255)\n"
"}")
self.widget.setObjectName("widget")
self.label = QtWidgets.QLabel(parent=self.widget)
self.label.setGeometry(QtCore.QRect(40, 30, 300, 420))
self.label.setStyleSheet("border-image: url(:/image/1618615593_15-phonoteka_org-p-temno-sinii-tsvet-fon-16.jpg);\n"
"border-radius:20px;\n"
"")
self.label.setText("")
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(parent=self.widget)
self.label_2.setGeometry(QtCore.QRect(50, 60, 280, 390))
font = QtGui.QFont()
font.setPointSize(3)
font.setBold(False)
font.setWeight(50)
self.label_2.setFont(font)
self.label_2.setStyleSheet("background-color:rgba(0,0,0,100);\n"
"border-radius:25px;")
self.label_2.setText("")
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(parent=self.widget)
self.label_3.setGeometry(QtCore.QRect(135, 90, 121, 51))
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.label_3.setFont(font)
self.label_3.setStyleSheet("color:rgba(255,255,255,210)")
self.label_3.setObjectName("label_3")
self.lineEdit = QtWidgets.QLineEdit(parent=self.widget)
self.lineEdit.setGeometry(QtCore.QRect(90, 150, 200, 40))
font = QtGui.QFont()
font.setPointSize(10)
self.lineEdit.setFont(font)
self.lineEdit.setStyleSheet("background-color:rgba(0,0,0,0);\n"
"border:none;\n"
"border-bottom:2px solid rgba(108,118,132,255);\n"
"color:rgba(255,255,255,230);\n"
"pading-bottom:7px;")
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtWidgets.QLineEdit(parent=self.widget)
self.lineEdit_2.setGeometry(QtCore.QRect(90, 220, 200, 40))
font = QtGui.QFont()
font.setPointSize(10)
self.lineEdit_2.setFont(font)
self.lineEdit_2.setStyleSheet("background-color:rgba(0,0,0,0);\n"
"border:none;\n"
"border-bottom:2px solid rgba(108,118,132,255);\n"
"color:rgba(255,255,255,230);\n"
"pading-bottom:7px;")
self.lineEdit_2.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
self.lineEdit_2.setObjectName("lineEdit_2")
self.pushLogin = QtWidgets.QPushButton(parent=self.widget)
self.pushLogin.setGeometry(QtCore.QRect(90, 290, 200, 40))
font = QtGui.QFont()
font.setPointSize(12)
font.setBold(True)
font.setWeight(75)
self.pushLogin.setFont(font)
self.pushLogin.setObjectName("pushLogin")
self.label_4 = QtWidgets.QLabel(parent=self.widget)
self.label_4.setGeometry(QtCore.QRect(110, 350, 201, 21))
self.label_4.setStyleSheet("color:rgba(255,255,255,140);")
self.label_4.setObjectName("label_4")
self.pushUrlDiscord = QtWidgets.QPushButton(parent=self.widget)
self.pushUrlDiscord.setGeometry(QtCore.QRect(90, 400, 30, 30))
self.pushUrlDiscord.setMaximumSize(QtCore.QSize(30, 30))
font = QtGui.QFont()
font.setFamily("Social Media Circled")
font.setPointSize(15)
self.pushUrlDiscord.setFont(font)
self.pushUrlDiscord.setObjectName("pushUrlDiscord")
self.pushUrlGitHub = QtWidgets.QPushButton(parent=self.widget)
self.pushUrlGitHub.setGeometry(QtCore.QRect(140, 400, 30, 30))
self.pushUrlGitHub.setMaximumSize(QtCore.QSize(30, 30))
font = QtGui.QFont()
font.setFamily("Social Media Circled")
font.setPointSize(15)
self.pushUrlGitHub.setFont(font)
self.pushUrlGitHub.setObjectName("pushUrlGitHub")
self.pushUrlFacebook = QtWidgets.QPushButton(parent=self.widget)
self.pushUrlFacebook.setGeometry(QtCore.QRect(190, 400, 30, 30))
self.pushUrlFacebook.setMaximumSize(QtCore.QSize(30, 30))
font = QtGui.QFont()
font.setFamily("Social Media Circled")
font.setPointSize(15)
self.pushUrlFacebook.setFont(font)
self.pushUrlFacebook.setObjectName("pushUrlFacebook")
self.pushUrlYouTube = QtWidgets.QPushButton(parent=self.widget)
self.pushUrlYouTube.setGeometry(QtCore.QRect(240, 400, 30, 30))
self.pushUrlYouTube.setMaximumSize(QtCore.QSize(30, 30))
font = QtGui.QFont()
font.setFamily("Social Media Circled")
font.setPointSize(15)
self.pushUrlYouTube.setFont(font)
self.pushUrlYouTube.setObjectName("pushUrlYouTube")
self.retranslateUi(ImageDialog)
QtCore.QMetaObject.connectSlotsByName(ImageDialog)
def retranslateUi(self, ImageDialog):
_translate = QtCore.QCoreApplication.translate
ImageDialog.setWindowTitle(_translate("ImageDialog", "Dialog"))
self.label_3.setText(_translate("ImageDialog", "Login in"))
self.lineEdit.setPlaceholderText(_translate("ImageDialog", "User Name"))
self.lineEdit_2.setPlaceholderText(_translate("ImageDialog", "Password"))
self.pushLogin.setText(_translate("ImageDialog", "L o g i n"))
self.label_4.setText(_translate("ImageDialog", "Введите ваш логин и пароль"))
self.pushUrlDiscord.setText(_translate("ImageDialog", "Y"))
self.pushUrlGitHub.setText(_translate("ImageDialog", ")"))
self.pushUrlFacebook.setText(_translate("ImageDialog", "E"))
self.pushUrlYouTube.setText(_translate("ImageDialog", "P"))
enter image description here
Position be so
And output like this
enter image description here
It seems that you're using a resource file (.qrc) for the image.
These files cannot be used directly in python, and require the use of the pyrcc tool, which creates a "compiled" python file that contains all resources when it is imported.
Unfortunately, the PyQt developer chose to stop supporting that tool since Qt6, claiming that, since python packages already use multiple files, having a single file for resources doesn't make a lot of sense (I understand his point of view, but I don't agree with it; he's the maintainer, though, and that's his choice).
Luckily, there's a solution: you can use the pyrcc5 tool (available with PyQt5), then open it and change the import statements on top from PyQt5 to PyQt6.
Otherwise, just don't use resources, and directly point to physical files.
Also see this related question: How can resources be provided in PyQt6 (which has no pyrcc)?

DropEvent does not work when dragging and dropping between widgets

I'm trying to get the behavior that when I drag and drop a MyButton, the dropEvent will be triggered in any part of the interface. Right now it works pretty much as needed, except for one thing. The dropEvent doesn't work if the mouse button is released between widgets, and I don't know how to fix this problem. For me it is very important that the dropEvent is always triggered, at the moment when the drag is finished, because at that moment I send a message to the server about the move made, and if at that moment the mouse was between the widgets, this message is not sent.
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'DS_Test.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QDragEnterEvent, QDropEvent
class MyButton(QtWidgets.QPushButton):
def mouseMoveEvent(self, event):
btn_img = self.grab()
painter = QtGui.QPainter(btn_img)
painter.setCompositionMode(painter.CompositionMode_DestinationIn)
painter.fillRect(btn_img.rect(), QtGui.QColor(0, 0, 0, 150))
painter.end()
data = QtCore.QMimeData()
drag = QtGui.QDrag(self)
drag.setMimeData(data)
drag.setPixmap(btn_img)
drag.setHotSpot(event.pos())
self._pos = event.pos()
drag.exec_(QtCore.Qt.CopyAction)
super(MyButton, self).mouseMoveEvent(event)
class MyFrame(QtWidgets.QFrame):
def __init__(self, parent):
super().__init__(parent)
self.setAcceptDrops(True)
def dragEnterEvent(self, e: QDragEnterEvent):
e.accept()
def dragMoveEvent(self, e):
e.accept()
def dropEvent(self, e: QDropEvent):
self.parent().dropEvent(e)
class MyQDialog(QtWidgets.QDialog):
def __init__(self):
super().__init__()
self.setAcceptDrops(True)
def dropEvent(self, e: QDropEvent):
print("dropEvent - is done")
e.accept()
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(1051, 800)
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalFrame = MyFrame(Dialog)
self.horizontalFrame.setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 0, 0, 211), stop:0.166 rgba(255, 255, 0, 211), stop:0.333 rgba(0, 255, 0, 211), stop:0.5 rgba(0, 255, 255, 211), stop:0.666 rgba(0, 0, 255, 211), stop:0.833 rgba(255, 0, 255, 211), stop:1 rgba(255, 0, 0, 211));")
self.horizontalFrame.setObjectName("horizontalFrame")
self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.horizontalFrame)
self.horizontalLayout_6.setObjectName("horizontalLayout_6")
self.pushButton_3 = MyButton(self.horizontalFrame)
self.pushButton_3.setObjectName("pushButton_3")
self.horizontalLayout_6.addWidget(self.pushButton_3)
self.pushButton_2 = MyButton(self.horizontalFrame)
self.pushButton_2.setObjectName("pushButton_2")
self.horizontalLayout_6.addWidget(self.pushButton_2)
self.pushButton = MyButton(self.horizontalFrame)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout_6.addWidget(self.pushButton)
self.verticalLayout.addWidget(self.horizontalFrame)
self.horizontalFrame_2 = MyFrame(Dialog)
self.horizontalFrame_2.setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(9, 41, 4, 255), stop:0.085 rgba(2, 79, 0, 255), stop:0.19 rgba(50, 147, 22, 255), stop:0.275 rgba(236, 191, 49, 255), stop:0.39 rgba(243, 61, 34, 255), stop:0.555 rgba(135, 81, 60, 255), stop:0.667 rgba(121, 75, 255, 255), stop:0.825 rgba(164, 255, 244, 255), stop:0.885 rgba(104, 222, 71, 255), stop:1 rgba(93, 128, 0, 255));")
self.horizontalFrame_2.setObjectName("horizontalFrame_2")
self.horizontalLayout_7 = QtWidgets.QHBoxLayout(self.horizontalFrame_2)
self.horizontalLayout_7.setObjectName("horizontalLayout_7")
self.verticalLayout.addWidget(self.horizontalFrame_2)
self.horizontalFrame_3 = MyFrame(Dialog)
self.horizontalFrame_3.setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(0, 0, 0, 255), stop:0.05 rgba(14, 8, 73, 255), stop:0.36 rgba(28, 17, 145, 255), stop:0.6 rgba(126, 14, 81, 255), stop:0.75 rgba(234, 11, 11, 255), stop:0.79 rgba(244, 70, 5, 255), stop:0.86 rgba(255, 136, 0, 255), stop:0.935 rgba(239, 236, 55, 255));")
self.horizontalFrame_3.setObjectName("horizontalFrame_3")
self.horizontalLayout_8 = QtWidgets.QHBoxLayout(self.horizontalFrame_3)
self.horizontalLayout_8.setObjectName("horizontalLayout_8")
self.verticalLayout.addWidget(self.horizontalFrame_3)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton_3.setText(_translate("Dialog", "PushButton"))
self.pushButton_2.setText(_translate("Dialog", "PushButton"))
self.pushButton.setText(_translate("Dialog", "PushButton"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = MyQDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
As recommended in the comment, I added dragEnterEvent and dragMoveEvent to MyQDialog. Now everything works the way I want it to. Here is the corrected code
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'DS_Test.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QDragEnterEvent, QDropEvent
class MyButton(QtWidgets.QPushButton):
def mouseMoveEvent(self, event):
btn_img = self.grab()
painter = QtGui.QPainter(btn_img)
painter.setCompositionMode(painter.CompositionMode_DestinationIn)
painter.fillRect(btn_img.rect(), QtGui.QColor(0, 0, 0, 150))
painter.end()
data = QtCore.QMimeData()
drag = QtGui.QDrag(self)
drag.setMimeData(data)
drag.setPixmap(btn_img)
drag.setHotSpot(event.pos())
self._pos = event.pos()
drag.exec_(QtCore.Qt.CopyAction)
super(MyButton, self).mouseMoveEvent(event)
class MyFrame(QtWidgets.QFrame):
def __init__(self, parent):
super().__init__(parent)
self.setAcceptDrops(True)
def dragEnterEvent(self, e: QDragEnterEvent):
e.accept()
def dragMoveEvent(self, e):
e.accept()
def dropEvent(self, e: QDropEvent):
self.parent().dropEvent(e)
class MyQDialog(QtWidgets.QDialog):
def __init__(self):
super().__init__()
self.setAcceptDrops(True)
def dragEnterEvent(self, e: QDragEnterEvent):
e.accept()
def dragMoveEvent(self, e):
e.accept()
def dropEvent(self, e: QDropEvent):
print("dropEvent - is done")
e.accept()
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(1051, 800)
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalFrame = MyFrame(Dialog)
self.horizontalFrame.setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 0, 0, 211), stop:0.166 rgba(255, 255, 0, 211), stop:0.333 rgba(0, 255, 0, 211), stop:0.5 rgba(0, 255, 255, 211), stop:0.666 rgba(0, 0, 255, 211), stop:0.833 rgba(255, 0, 255, 211), stop:1 rgba(255, 0, 0, 211));")
self.horizontalFrame.setObjectName("horizontalFrame")
self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.horizontalFrame)
self.horizontalLayout_6.setObjectName("horizontalLayout_6")
self.pushButton_3 = MyButton(self.horizontalFrame)
self.pushButton_3.setObjectName("pushButton_3")
self.horizontalLayout_6.addWidget(self.pushButton_3)
self.pushButton_2 = MyButton(self.horizontalFrame)
self.pushButton_2.setObjectName("pushButton_2")
self.horizontalLayout_6.addWidget(self.pushButton_2)
self.pushButton = MyButton(self.horizontalFrame)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout_6.addWidget(self.pushButton)
self.verticalLayout.addWidget(self.horizontalFrame)
self.horizontalFrame_2 = MyFrame(Dialog)
self.horizontalFrame_2.setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(9, 41, 4, 255), stop:0.085 rgba(2, 79, 0, 255), stop:0.19 rgba(50, 147, 22, 255), stop:0.275 rgba(236, 191, 49, 255), stop:0.39 rgba(243, 61, 34, 255), stop:0.555 rgba(135, 81, 60, 255), stop:0.667 rgba(121, 75, 255, 255), stop:0.825 rgba(164, 255, 244, 255), stop:0.885 rgba(104, 222, 71, 255), stop:1 rgba(93, 128, 0, 255));")
self.horizontalFrame_2.setObjectName("horizontalFrame_2")
self.horizontalLayout_7 = QtWidgets.QHBoxLayout(self.horizontalFrame_2)
self.horizontalLayout_7.setObjectName("horizontalLayout_7")
self.verticalLayout.addWidget(self.horizontalFrame_2)
self.horizontalFrame_3 = MyFrame(Dialog)
self.horizontalFrame_3.setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(0, 0, 0, 255), stop:0.05 rgba(14, 8, 73, 255), stop:0.36 rgba(28, 17, 145, 255), stop:0.6 rgba(126, 14, 81, 255), stop:0.75 rgba(234, 11, 11, 255), stop:0.79 rgba(244, 70, 5, 255), stop:0.86 rgba(255, 136, 0, 255), stop:0.935 rgba(239, 236, 55, 255));")
self.horizontalFrame_3.setObjectName("horizontalFrame_3")
self.horizontalLayout_8 = QtWidgets.QHBoxLayout(self.horizontalFrame_3)
self.horizontalLayout_8.setObjectName("horizontalLayout_8")
self.verticalLayout.addWidget(self.horizontalFrame_3)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton_3.setText(_translate("Dialog", "PushButton"))
self.pushButton_2.setText(_translate("Dialog", "PushButton"))
self.pushButton.setText(_translate("Dialog", "PushButton"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = MyQDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())

matplotlib grouped bar color change

I am trying to compare group A and group B using grouped bar, but group A must have the same colors and group B must have different colors and legends. I somehow created graph, but not sure how to change the color of each group B bar graphs..
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
labels = ['M1', 'A1', 'M2', 'A2', 'M3', 'A3', 'M4', 'A4', 'M5', 'A5']
A_group = [20, 34, 30, 35, 27, 17, 64, 23, 47, 52]
B_group = [25, 32, 34, 20, 25, 76, 33, 54, 16, 21]
x = np.arange(len(labels)) # the label locations
width = 0.35 # the width of the bars
fig, ax = plt.subplots()
rects1 = ax.bar(x - width/2, A_group, width, label='A group')
rects2 = ax.bar(x + width/2, B_group, width, label='B group')
# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel('Accuracy')
ax.set_title('Test')
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.legend()
ax.bar_label(rects1, padding=3)
ax.bar_label(rects2, padding=3)
plt.xticks(rotation=30, ha='right')
plt.ylim(0, 100)
fig.tight_layout()
plt.show()
Now my graph looks like this:
I want to make my graph like this. Below is an example using powerpoint.
Any helps will be appreciated. Thank you in advance.
Try drawing the bars in B_group one by one:
fig, ax = plt.subplots()
ax.bar(x-width/2, A_group, width=width,label='A Group')
cmap = plt.get_cmap('tab20')
ax.set_prop_cycle(color=[cmap(k) for k in x+1])
for i in x:
ax.bar(i+width/2, B_group[i], width=width)
Output:

Pollution rose plot gridded

I am trying to create a pollution rose plot as described in the link Plotting Windrose: making a pollution rose with concentration set to color
Example in the reply is working but when I used my data then it is giving a weird plot. Any advice where I am going wrong? Thank you.
import matplotlib.pyplot as plt
import numpy as np
wd = [90.,297.,309.,336.,20.,2.,334.,327.,117.,125.,122.,97.,95.,97.,103.,106.,125.,148.,147.,140.,141.,145.,144.,151.,161.]
ws = [15,1.6,1.8,1.7,2.1,1.6,2.1,1.4,3,6.5,7.1,8.2,10.2,10.2,10.8,10.2,11.4,9.7,8.6,7.1,6.4,5.5,5,5,6]
oz = [10.,20.,30.,40.,50.,60.,70.,80.,90.,100.,110.,120.,90.,140.,100.,106.,125.,148.,147.,140.,141.,145.,144.,151.,161.]
pi_fac = 22/(7*180.)
wd_rad = [w * pi_fac for w in wd]
ws_r = np.linspace(min(ws),max(ws),16)
WD,WS = np.meshgrid(wd_rad,ws_r)
C = oz + np.zeros((len(ws_r),len(wd)),dtype=float)
C = np.ma.masked_less_equal(C,10)
fig, ax = plt.subplots(subplot_kw={"projection":"polar"})
ax.pcolormesh(WD,WS,C,vmin=10, vmax=170) # I tried different vmin and vmax too
plt.show()
The linked post assumes you have a regular grid for directions and for speeds, but your input seems to be quite unordered combinations.
To create a plot with colored regions depending on the oz values, you could try tricontourf. tricontourf takes in X, Y and Z values that don't need to lie on a grid and creates a contour plot. Although it is meant for rectangular layouts, it might also work for your case. It will have a discontinuity though, when crossing from 360º to 0º.
The plot of this example also draws a colorbar to show which range of oz values correspond to which color. vmin and vmax can change this mapping of colors.
import matplotlib.pyplot as plt
import numpy as np
wd = [90, 297, 309, 336, 20, 2, 334, 327, 117, 125, 122, 97, 95, 97, 103, 106, 125, 148, 147, 140, 141, 145, 144, 151, 161]
ws = [15, 1.6, 1.8, 1.7, 2.1, 1.6, 2.1, 1.4, 3, 6.5, 7.1, 8.2, 10.2, 10.2, 10.8, 10.2, 11.4, 9.7, 8.6, 7.1, 6.4, 5.5, 5, 5, 6]
oz = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 90, 140, 100, 106, 125, 148, 147, 140, 141, 145, 144, 151, 161]
fig, ax = plt.subplots(subplot_kw={"projection": "polar"})
cont = ax.tricontourf(np.radians(np.array(wd)), ws, oz, cmap='hot')
plt.colorbar(cont)
plt.show()
With ax.scatter(np.radians(np.array(wd)), ws, c=oz, cmap='hot', vmax=250) you could create a scatter plot to get an idea how the input looks like when colored.
You might want to incorporate Python's windrose library to get polar plots to resemble a windrose.
Another approach, which might be closer to the one intended by the linked question, would be to use scipy's interpolate.griddata to map the data to a grid. To get rid of the areas without data, an 'under' color of 'none' can be used, provided that vmin is higher than zero.
import matplotlib.pyplot as plt
import numpy as np
from scipy import interpolate
wd = [90, 297, 309, 336, 20, 2, 334, 327, 117, 125, 122, 97, 95, 97, 103, 106, 125, 148, 147, 140, 141, 145, 144, 151, 161]
ws = [15, 1.6, 1.8, 1.7, 2.1, 1.6, 2.1, 1.4, 3, 6.5, 7.1, 8.2, 10.2, 10.2, 10.8, 10.2, 11.4, 9.7, 8.6, 7.1, 6.4, 5.5, 5, 5, 6]
oz = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 90, 140, 100, 106, 125, 148, 147, 140, 141, 145, 144, 151, 161]
wd_rad = np.radians(np.array(wd))
oz = np.array(oz, dtype=np.float)
WD, WS = np.meshgrid(np.linspace(0, 2*np.pi, 36), np.linspace(min(ws), max(ws), 16 ))
Z = interpolate.griddata((wd_rad, ws), oz, (WD, WS), method='linear')
fig, ax = plt.subplots(subplot_kw={"projection": "polar"})
cmap = plt.get_cmap('hot')
cmap.set_under('none')
img = ax.pcolormesh(WD, WS, Z, cmap=cmap, vmin=20)
plt.colorbar(img)
plt.show()

matplotlib histogram with equal bars width

I use a histogram to display the distribution. Everything works fine if the spacing of the bins is uniform. But if the interval is different, then the bar width is appropriate (as expected). Is there a way to set the width of the bar independent of the size of the bins ?
This is what i have
This what i trying to draw
from matplotlib import pyplot as plt
my_bins = [10, 20, 30, 40, 50, 120]
my_data = [5, 5, 6, 8, 9, 15, 25, 27, 33, 45, 46, 48, 49, 111, 113]
fig1 = plt.figure()
ax1 = fig1.add_subplot(121)
ax1.set_xticks(my_bins)
ax1.hist(my_data, my_bins, histtype='bar', rwidth=0.9,)
fig1.show()
I cannot mark your question as a duplicate, but I think my answer to this question might be what you are looking for?
I'm not sure how you'll make sense of the result, but you can use numpy.histogram to calculate the height of your bars, then plot those directly against an arbitrary x-scale.
x = np.random.normal(loc=50, scale=200, size=(2000,))
bins = [0,1,10,20,30,40,50,75,100]
fig = plt.figure()
ax = fig.add_subplot(211)
ax.hist(x, bins=bins, edgecolor='k')
ax = fig.add_subplot(212)
h,e = np.histogram(x, bins=bins)
ax.bar(range(len(bins)-1),h, width=1, edgecolor='k')
EDIT Here's with the adjustment to the x-tick labels so that the correspondence is easier to see.
my_bins = [10, 20, 30, 40, 50, 120]
my_data = [5, 5, 6, 8, 9, 15, 25, 27, 33, 45, 46, 48, 49, 111, 113]
fig = plt.figure()
ax = fig.add_subplot(211)
ax.hist(my_data, bins=my_bins, edgecolor='k')
ax = fig.add_subplot(212)
h,e = np.histogram(my_data, bins=my_bins)
ax.bar(range(len(my_bins)-1),h, width=1, edgecolor='k')
ax.set_xticks(range(len(my_bins)-1))
ax.set_xticklabels(my_bins[:-1])