Ich habe ein Matplotlib-Plot in einem Gtk + -Fenster gekapselt und ich versuche, dieses Plot zu aktualisieren, wenn eine Schaltfläche angeklickt wird (es ist Gauss 'Kreis-Problem). Das Problem ist, ich bin mir nicht sicher, wie ich die Handlung mit einem Event aktualisieren soll. Bisher habe ich folgendes.Update Matplotlib-Plot mit Gtk + Button Ereignis
#! /usr/bin/env python3.4
# -*- coding: utf-8 -*-
""" Main application--embed Matplotlib figure in window with UI """
import gi
gi.require_version('Gtk', '3.0')
import numpy as np
from gi.repository import Gtk, GObject
from matplotlib.figure import Figure
# make sure cairocffi is installed, pycairo doesn't support FigureCanvasGTK3Agg
from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg \
as FigureCanvas
from matplotlib.patches import Ellipse
from typing import List, Tuple
from math import sqrt
class Main(Gtk.Window):
""" Main window UI """
SIGMA = 10
def __init__(self):
Gtk.Window.__init__(self, title='Gauss\' Circle Problem')
self.connect('destroy', lambda _: Gtk.main_quit())
self.set_border_width(10)
self.set_default_size(600, 450)
# Set up the l/r box layout
self.box = Gtk.Box(spacing=10)
self.add(self.box)
# Set up the right column
self.rcolumn = Gtk.Grid()
self.box.pack_end(self.rcolumn, False, False, 1)
# Set up spin button
adjustment = Gtk.Adjustment(10, 3, 100, 1, 0, 0)
self.spinbutton = Gtk.SpinButton()
self.spinbutton.set_adjustment(adjustment)
self.rcolumn.attach(self.spinbutton, 0, 0, 1, 1)
# Set up update button
self.update_plot_button = Gtk.Button(label='Update')
self.update_plot_button.connect('clicked', self.update_sigma_event)
self.rcolumn.attach_next_to(self.update_plot_button,
self.spinbutton, Gtk.PackDirection.BTT, 1, 1)
self._add_plot()
def update_sigma_event(self, button) -> None:
""" Update sigma and replot """
self.SIGMA = self.spinbutton.get_value()
self._add_plot()
def _add_plot(self) -> None:
""" Add the plot to the window """
fig = Figure(figsize=(5, 4))
ax = fig.add_subplot(111, aspect='equal')
arr = np.zeros([self.SIGMA * 2 + 1] * 2)
points = self.collect(int(self.SIGMA), int(self.SIGMA), self.SIGMA)
# flip pixel value if it lies inside (or on) the circle
for p in points:
arr[p] = 1
# plot ellipse on top of boxes to show their centroids lie inside
circ = Ellipse(\
xy=(int(self.SIGMA), int(self.SIGMA)),
width=2 * self.SIGMA,
height=2 * self.SIGMA,
angle=0.0
)
ax.add_artist(circ)
circ.set_clip_box(ax.bbox)
circ.set_alpha(0.2)
circ.set_facecolor((1, 1, 1))
ax.set_xlim(-0.5, 2 * self.SIGMA + 0.5)
ax.set_ylim(-0.5, 2 * self.SIGMA + 0.5)
# Plot the pixel centers
ax.scatter(*zip(*points), marker='.', color='white')
# now plot the array that's been created
ax.imshow(-arr, interpolation='none', cmap='gray')
# add it to the window
canvas = FigureCanvas(fig)
self.box.pack_start(canvas, True, True, 0)
@staticmethod
def collect(x: int, y: int, sigma: float =3.0) -> List[Tuple[int, int]]:
""" create a small collection of points in a neighborhood of some
point
"""
neighborhood = []
X = int(sigma)
for i in range(-X, X + 1):
Y = int(pow(sigma * sigma - i * i, 1/2))
for j in range(-Y, Y + 1):
neighborhood.append((x + i, y + j))
return neighborhood
if __name__ == '__main__':
window = Main()
window.show_all()
Gtk.main()
ich nicht ganz sicher bin, wo von hier zu gehen, ich weiß nur, dass die SpinButton
tatsächlich Aktualisierung self.SIGMA
paßt, aber ich weiß nicht, wie matplotlib zu sagen, die Handlung in dem Fenster zu aktualisieren.
Auch dieses ist, wie es zur Zeit aussieht, wenn Sie nicht in der Lage sind, es zu laufen (Ich versuche auch vertikal zentriert die beiden Taste Widgets in der rechten Spalte: P):