Всплывающие аннотации на matplotlib в wxPython
У меня есть двухпанельный wxPython GUI. На правой панели у меня есть отображение карты с использованием базовой карты. На этой базовой карте (Соединенных Штатов) я нарисую точечный график разных городов. Я хотел бы иметь возможность нажимать на эти точки и иметь всплывающее окно в моем GUI, которое дает некоторую информацию относительно той точки, которую я выбираю (например, город, широта / долгота и т. Д. - я хотел бы сохранить всю эту информацию в списке или другими средствами).
Я сталкивался с AnnoteFinder, но это, кажется, не работает внутри моего GUI (это будет работать, если я использую Basemap от itelf, а не в моем 2-панельном GUI). Кроме того, это просто помещает некоторый текст поверх точки - я бы предпочел, чтобы появилось небольшое окно.
Пример моего кода пока:
#Setting up Map Figure
self.figure = Figure(None,dpi=75)
self.canvas = FigureCanvas(self.PlotPanel, -1, self.figure)
self.axes = self.figure.add_axes([0,0,1,1],frameon=False)
self.SetColor( (255,255,255) )
#Basemap Setup
self.map = Basemap(llcrnrlon=-119, llcrnrlat=22, urcrnrlon=-64,
urcrnrlat=49, projection='lcc', lat_1=33, lat_2=45,
lon_0=-95, resolution='h', area_thresh=10000,ax=self.axes)
self.map.drawcoastlines()
self.map.drawcountries()
self.map.drawstates()
self.figure.canvas.draw()
#Set up Scatter Plot
m = Basemap(llcrnrlon=-119, llcrnrlat=22, urcrnrlon=-64,
urcrnrlat=49, projection='lcc', lat_1=33, lat_2=45,
lon_0=-95, resolution='h', area_thresh=10000,ax=self.axes)
x,y=m(Long,Lat)
#Scatter Plot (they plot the same thing)
self.map.plot(x,y,'ro')
self.map.scatter(x,y,90)
self.figure.canvas.draw()
Какие-нибудь мысли?
1 ответ
Проверьте этот ответ. В основном вы устанавливаете событие выбора, которое создает аннотацию на графике. Эта аннотация может появляться как текстовое поле в виде всплывающей подсказки.
Обратите внимание, что это не создает реального окна GUI (т. Е. Диалогового окна или другого элемента управления с кнопкой закрытия, строки заголовка и т. Д.), А просто аннотацию на самом графике. Однако, посмотрев на код, вы увидите, как он определяет исполнителя (например, точку), по которой вы щелкнули. Получив эту информацию, вы можете запускать любой код, какой захотите, например, создавая диалоговое окно wxPython вместо аннотации.
Отредактируйте ваш вопрос о последних нескольких строках: Исходя из вашего кода, похоже, что вы захотите сделать:
pts = self.map.scatter(x, y, 90)
self.figure.canvas.mpl_connect('pick_event', DataCursor(plt.gca()))
pts.set_picker(5)
Еще одно изменение, касающееся вопроса о наличии другого текста в аннотации: возможно, вам придется немного поиграться с объектом события, чтобы извлечь нужную информацию. Как описано на http://matplotlib.sourceforge.net/users/event_handling.html, разные типы исполнителей (т.е. разные типы графиков) будут предоставлять разную информацию о событиях.
У меня есть какой-то старый код, который делает почти точно то, что вы описали (отображение названия города при нажатии на точку на карте). Я должен признать, что не помню точно, как все это работает, но мой код имеет это в DataCursor:
def __call__(self, event):
self.event = event
xdata, ydata = event.artist._offsets[:,0], event.artist._offsets[:,1]
#self.x, self.y = xdata[event.ind], ydata[event.ind]
self.x, self.y = event.mouseevent.xdata, event.mouseevent.ydata
if self.x is not None:
city = clim['Name'][event.ind[0]]
if city == self.annotation.get_text() and self.annotation.get_visible():
# You can click the visible annotation to remove it
self.annotation.set_visible(False)
event.canvas.draw()
return
self.annotation.xy = self.x, self.y
self.annotation.set_text(city)
self.annotation.set_visible(True)
event.canvas.draw()
clim['Name']
это список названий городов, и я смог проиндексировать это с помощью event.ind
чтобы получить название города, соответствующее выбранной точке. Ваш код может немного отличаться в зависимости от формата ваших данных, но это должно дать вам представление.