python - 在 Python GUI 中使用 basemap 作为图形

标签 python matplotlib tkinter matplotlib-basemap

我有生成 basemap 的代码片段,以及 GUI 的(非常粗略的)开始。但是,我找不到“one-liner”可以让我在 GUI 中将 map 显示为图形。代码片段如下;理想情况下,我希望发生几件事:

  1. 用于替换 sin(2*pi*t) 绘图的“ basemap ”图像
  2. 如果我单击显示的图,我真的希望代码能够记录图形上的(像素)位置(希望您可以单击 map 上的任意位置,并且脚本将记录纬度以及您点击位置的经度)。

关于第一步,我尝试过将图形变量 f 设置为等于 basemap 等;这完全杀死了 GUI 部分,只是在另一个窗口中显示了 map 的图像。

我尝试通过实现在 stackexchange 上找到的几个例程来解决问题 2,但从未使其完全正常工作。

basemap :

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

## User-chosen datapoint
#lons = [10]; lats = [20];

# Define map projection
m = Basemap(projection='cyl',llcrnrlat=-90,urcrnrlat=90,\
            llcrnrlon=-180,urcrnrlon=180,resolution='c')
m.drawcoastlines()

粗糙的 GUI:

import matplotlib
matplotlib.use('TkAgg')

from numpy import arange, sin, pi
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
# implement the default mpl key bindings
from matplotlib.backend_bases import key_press_handler

from Tkinter import *
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

from PIL import Image
from mpl_toolkits.basemap import Basemap

from matplotlib.figure import Figure

import sys
if sys.version_info[0] < 3:
    import Tkinter as Tk
else:
    import tkinter as Tk

root = Tk.Tk()
root.wm_title("Embedding in TK")

f = Figure(figsize=(5, 4), dpi=100)
a = f.add_subplot(111)
t = arange(0.0, 3.0, 0.01)
s = sin(2*pi*t)

a.plot(t, s)

# a tk.DrawingArea
canvas = FigureCanvasTkAgg(f, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

toolbar = NavigationToolbar2TkAgg(canvas, root)
toolbar.update()
canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

def on_key_event(event):
    print('you pressed %s' % event.key)
    key_press_handler(event, canvas, toolbar)

canvas.mpl_connect('key_press_event', on_key_event)

def _quit():
    root.quit()     # stops mainloop
    root.destroy()  # this is necessary on Windows to prevent
                    # Fatal Python Error: PyEval_RestoreThread: NULL tstate
button = Tk.Button(master=root, text='Quit', command=_quit)
button.pack(side=Tk.BOTTOM)

Tk.mainloop()

最佳答案

如何将 basemap 包含到 Tkinter 中的问题实际上尚未得到解答。因此,我们的想法是在图中创建一个轴 ax 并将 basemap 添加到轴中。这是通过 ax 参数完成的,

m = Basemap(..., ax=ax)

然后将图形以通常的方式添加到 Canvas 上;下面是一个完整的示例。

from mpl_toolkits.basemap import Basemap
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure

import sys
if sys.version_info[0] < 3:
    import Tkinter as Tk
else:
    import tkinter as Tk

root = Tk.Tk()
root.wm_title("Embedding in TK")

fig = Figure(figsize=(5, 4), dpi=100)
ax = fig.add_subplot(111)

m = Basemap(projection='cyl',llcrnrlat=-90,urcrnrlat=90,\
            llcrnrlon=-180,urcrnrlon=180,resolution='c', ax=ax)
m.drawcoastlines()

# a tk.DrawingArea
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

toolbar = NavigationToolbar2TkAgg(canvas, root)
toolbar.update()
canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

def _quit():
    root.quit()     # stops mainloop
    root.destroy()  # this is necessary on Windows to prevent
                    # Fatal Python Error: PyEval_RestoreThread: NULL tstate
button = Tk.Button(master=root, text='Quit', command=_quit)
button.pack(side=Tk.BOTTOM)

Tk.mainloop()

enter image description here

注意:在较新版本的 matplotlib 中,您应该使用 NavigationToolbar2Tk 而不是 NavigationToolbar2TkAgg

关于python - 在 Python GUI 中使用 basemap 作为图形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35164123/

相关文章:

python - Tkinter - 使用循环创建多个复选框

python - PyTorch-获取 'TypeError: pic should be PIL Image or ndarray. Got <class ' numpy.ndarray'>'错误

python - 初始化实例变量的最 Pythonic 方式

python - Pygubu 从 UI 文件加载新窗口

python - 在 tkinter 中运行 matplotlib

python - matplotlib - pandas - 子图中的 twinx 轴没有 xlabel 和 xticks

python - 使用 Matplotlib 绘制 Takagi 函数

Python在方法内使用tkinter显示变量

python - 为什么这会创建 2 个窗口?

python pandas dataframe 将 NaN 更改为零