【问题标题】:Basemap / PySide QWidget: Drawing text onto mapBasemap / PySide QWidget:在地图上绘制文本
【发布时间】:2017-07-03 19:03:36
【问题描述】:

我在将文本写入 PySide QWidget 内的 Basemap 时遇到了困难。根据我在网上找到的信息,人们会这样做:

import matplotlib.pyplot as plt
...
plt.text(x, y, 'some text')

但是当我用我的代码尝试类似的事情时,它会弹出另一个带有文本的窗口,而不是在小部件内的地图上。

Basemap 没有像 text() 这样的方法,所以我一直不知道该怎么做。有人对在这种情况下如何将文本绘制到底图有想法吗?

完整代码:

'''
This program should draw a dot on a random point on Earth and label it 'Point'
You'll probably attempt to do this on line 43 in changeMap()
'''

from PySide import QtCore, QtGui

import matplotlib
matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4']='PySide'
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
from mpl_toolkits.basemap import Basemap

from random import randint

class MapWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.figure = Figure()
        self.canvas = FigureCanvas(self.figure)
        self.layout = QtGui.QVBoxLayout(self)
        self.mplToolbar = NavigationToolbar(self.canvas, self, coordinates=False)
        self.layout.addWidget(self.canvas)
        self.layout.addWidget(self.mplToolbar)
        self.axes = self.figure.add_subplot(111)
        self.setLayout(self.layout)
        # Create our Basemap
        self.map = Basemap(projection='robin', lon_0=0, ax=self.axes, resolution='c')
        self.map.drawcoastlines()
        self.map.drawcountries()
        # Create empty plot to store random coordinates in for later
        self.points, = self.map.plot([], [], 'o')
        # Draw to screen
        self.canvas.draw()
        self.show()

    def changeMap(self, lat, lon, text):
        x, y = self.map(lon, lat)
        self.points.set_data(x, y)
        # Draw text here

        self.canvas.draw()


class Ui_MainWindow(object):
    def plot(self):
        # Plot on some random coordinate and label it 'Point'
        self.Map.changeMap(randint(-90, 90), randint(-180, 180), 'Point')

    def myChanges(self):
        # Initialize our Basemap
        self.Map = MapWidget()
        self.layoutMap = QtGui.QVBoxLayout(self.widget)
        self.layoutMap.addWidget(self.Map)
        # Plot a new point when the button is clicked
        self.pushButton.clicked.connect(self.plot)

    # The following is all PySide code, not very relevant to the question
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayout_2 = QtGui.QHBoxLayout(self.centralwidget)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.horizontalLayout = QtGui.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setMaximumSize(QtCore.QSize(100, 16777215))
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout.addWidget(self.pushButton)
        self.widget = QtGui.QWidget(self.centralwidget)
        self.widget.setObjectName("widget")
        self.horizontalLayout.addWidget(self.widget)
        self.horizontalLayout_2.addLayout(self.horizontalLayout)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        self.myChanges()

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton.setText(QtGui.QApplication.translate("MainWindow", "Plot", None, QtGui.QApplication.UnicodeUTF8))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

【问题讨论】:

    标签: python matplotlib pyside matplotlib-basemap matplotlib-widget


    【解决方案1】:

    要在底图上获取文本,您可以将该文本添加到坐标区。您已将它们存储在self.axes 中。 在这里您将创建一个空文本

    # Create empty plot to store random coordinates in for later
    self.points, = self.map.plot([], [], 'o')
    self.pointsannotate = self.axes.text(0,0,"", color="crimson")
    

    稍后更新文本的位置和字符串:

    def changeMap(self, lat, lon, text):
        x, y = self.map(lon, lat)
        self.points.set_data(x, y)
        # Draw text here
        self.pointsannotate.set_position([x,y])
        self.pointsannotate.set_text("{},{}".format(lon, lat))
    
        self.canvas.draw()
    

    【讨论】:

    • 谢谢!有没有办法为 self.pointsannotate 变量设置多个文本和多个位置,或者它一次只能处理一个点?在我看来,我必须创建一个长度为 x 的 axes.text 对象列表,其中 x 是我要标记的点数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    • 2011-05-25
    相关资源
    最近更新 更多