Python Kivy 绘图与 MeshLinePlot 混淆

标签 python plot kivy kivy-language

我正在尝试在 Kivy 应用程序中实现实时测量绘图,但我不了解 kivy 花园库的内部工作原理。

我想要实现的目标:我希望在 ScrollView 中包含多个绘图,以便我可以通过编程方式从字典添加多个实时绘图并滚动浏览如果它们占据的空间超过一个屏幕的高度。我遇到的主要问题是图表的行为不像普通的小部件,而是像 Canvas 。我已经尝试使用 matplotlib 作为 backend_kivyagg 来实现这一点,但我未能为每个 subplot that I created 提供固定的大小.

有很多事情我不明白为什么它们会发生。

from math import sin, cos

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.uix.widget import Widget

from kivy.garden.graph import Graph, MeshLinePlot


class Plot(Widget):
    def __init__(self):
        super(Plot, self).__init__()
        self.graph = Graph(xlabel="x", ylabel="y", x_ticks_minor=5, x_ticks_major=25, y_ticks_major=1,
                           y_grid_label=True, x_grid_label=True, x_grid=True, y_grid=True,
                           xmin=-0, xmax=100, ymin=-1, ymax=1, draw_border=False)
        # graph.size = (1200, 400)
        # self.graph.pos = self.center

        self.plot = MeshLinePlot(color=[1, 1, 1, 1])
        self.plot.points = [(x, sin(x / 10.)) for x in range(0, 101)]
        self.plot2 = MeshLinePlot(color=[1, 0, 0, 1])
        self.plot2.points = [(x, cos(x / 10.)) for x in range(0, 101)]
        self.add_widget(self.graph)

        self.graph.add_plot(self.plot)
        self.graph.add_plot(self.plot2)


class GraphLayoutApp(App):

    def build(self):
        scroll_view = ScrollView()
        grid_layout = GridLayout(cols=1, row_force_default=True, padding=20, spacing=20)
        graph = Plot()
        graph2 = Plot()
        label = Label(text="Hello World!")
        label2 = Label(text="Hello World!")
        grid_layout.add_widget(label)
        grid_layout.add_widget(graph)
        grid_layout.add_widget(label2)
        grid_layout.add_widget(graph2)
        scroll_view.add_widget(grid_layout)

        return scroll_view


if __name__ == '__main__':
    GraphLayoutApp().run()

Questions:

  1. Inside the class GraphLayoutApp I create two objects graph and graph2 but if I add them to the GridLayout() only one does appear? How can I add multiple graphs?

  2. Also Inside the build method of the class GraphLayoutApp I create two lables. I wanted to first display the first label then the graph and then the second label label2. But it seems to me that the graph is always displayed in the lower left corner. I guess this has to do with the canvas on which it is drawn, but I cannot solve it.

最佳答案

这是修改后的版本,修复了一些问题:

这里的问题是你让你的 Plot 继承自 Widget,它实际上是框架中最基本的小部件,并且由于它不是布局,因此不管理您添加到其中的子级中的任何内容,因此 Graph 小部件您添加到它的内容保留在默认大小/位置(分别为 [100, 100] 和 [0, 0]),因此它们彼此堆叠,我使用了relativelayout,它将子项默认设置为其自己的大小和位置,因此图表跟随小部件。另一个解决方案是简单地使 Plot 继承自 Graph,因为它是唯一的子项,并使用“self.add_plot”而不是“self.graph.add_plot”,并覆盖 Graph 参数,最好的解决方案可能是创建一个Plot 类的 KV 规则。但第一个解决方案是对代码进行最小的更改。

您错过的一般原则是,在 kivy 中,小部件默认情况下不受任何位置/大小的限制,除非它们的父级是专门管理该布局的布局(就像 GridLayout 对标签所做的那样)。

我还使 GridLayout 自动将其自身调整为最小大小(由我放入所有小部件中的硬编码大小确定),因此您实际上可以滚动一些内容。

这段代码也非常Python驱动,在kivy中,你通常想使用KV做更多的事情,而不是使用add_widget来做静态的事情。

from math import sin, cos

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.uix.widget import Widget
from kivy.uix.relativelayout import RelativeLayout

from kivy_garden.graph import Graph, MeshLinePlot


class Plot(RelativeLayout):
    def __init__(self, **kwargs):
        super(Plot, self).__init__(**kwargs)
        self.graph = Graph(xlabel="x", ylabel="y", x_ticks_minor=5, x_ticks_major=25, y_ticks_major=1,
                           y_grid_label=True, x_grid_label=True, x_grid=True, y_grid=True,
                           xmin=-0, xmax=100, ymin=-1, ymax=1, draw_border=False)
        # graph.size = (1200, 400)
        # self.graph.pos = self.center

        self.plot = MeshLinePlot(color=[1, 1, 1, 1])
        self.plot.points = [(x, sin(x / 10.)) for x in range(0, 101)]
        self.plot2 = MeshLinePlot(color=[1, 0, 0, 1])
        self.plot2.points = [(x, cos(x / 10.)) for x in range(0, 101)]
        self.add_widget(self.graph)

        self.graph.add_plot(self.plot)
        self.graph.add_plot(self.plot2)


class GraphLayoutApp(App):

    def build(self):
        scroll_view = ScrollView()
        grid_layout = GridLayout(cols=1, padding=20, spacing=20, size_hint_y=None)
        grid_layout.bind(minimum_size=grid_layout.setter('size'))
        graph = Plot(size_hint_y=None, height=500)
        graph2 = Plot(size_hint_y=None, height=500)
        label = Label(text="Hello World!", size_hint_y=None)
        label2 = Label(text="Hello World!", size_hint_y=None)
        grid_layout.add_widget(label)
        grid_layout.add_widget(graph)
        grid_layout.add_widget(label2)
        grid_layout.add_widget(graph2)
        scroll_view.add_widget(grid_layout)

        # return grid_layout
        return scroll_view


if __name__ == '__main__':
    GraphLayoutApp().run()

关于Python Kivy 绘图与 MeshLinePlot 混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52200823/

相关文章:

python - 无法在 kivy 中打开窗口

python - 调整 TensorFlow 代码丢弃层以允许导入到 openCV

python - 如何从 python 中的文件编码为 ascii、base64、hex

r - 如何通过 R 创建 GUI?

python - 如何设置图例标记大小和 alpha?

python - 基维。文本提供者错误

python - 如何在python中处理结构化语言文件

python - 设置索引的方式有什么区别

r - 如何在 R 中的绘图文本中包含斜体和下标

python - 在 kivy 小部件中访问父对象的大小参数