【问题标题】:Using matplotlib in pygame在 pygame 中使用 matplotlib
【发布时间】:2018-06-14 01:42:29
【问题描述】:

我在这里有一个大问题 - 我想大多数人不会喜欢这个问题,我可能会因为是菜鸟而受到抨击,但不管怎样,这就是问题。

我正在尝试使用 matplotlib 在我的 pygame 程序中实现条形图。我设法很简单地做到了,但没有使用 pygame。

我已经设法制作了一个条形图,但我无法将其放入 pygame:

names = ['a', 'b', 'c']
values = [1, 10, 100]
plt.figure(1, figsize=(9, 3))
plt.bar(names, values)
plt.show()

我想在我的 pygame 游戏中实现这一点,但老实说我不知道​​从哪里开始。这是一个下周到期的项目。谢谢。

【问题讨论】:

    标签: python python-3.x matplotlib pygame


    【解决方案1】:

    您可能想看看这个试图为 matplotlib 创建适当的 pygame 后端的库。 https://pypi.org/project/pygame-matplotlib/

    目前处于测试阶段,但看起来很有希望。

    【讨论】:

      【解决方案2】:

      接受的答案没有解释如何设置线条颜色、线条样式等。所以这就是我发现的,希望它对其他人有用。

      您将需要一个有效的 python-tk 并使用 pip 安装 pygame 和 matplotlib。以下代码在 Ubuntu 18.04 上使用 python3、pygame 2.0.1 和 matplotlib 3.3.4 进行了测试。

      一些关于如何自定义代码的链接:

      import matplotlib
      import matplotlib.pyplot as plt
      import matplotlib.backends.backend_agg as agg
      import pygame
      from pygame.locals import *
      import pylab
      
      matplotlib.use("Agg")
      
      plt.rcParams.update({
          "lines.marker": "o",         # available ('o', 'v', '^', '<', '>', '8', 's', 'p', '*', 'h', 'H', 'D', 'd', 'P', 'X')
          "lines.linewidth": "1.8",
          "axes.prop_cycle": plt.cycler('color', ['white']),  # line color
          "text.color": "white",       # no text in this example
          "axes.facecolor": "black",   # background of the figure
          "axes.edgecolor": "lightgray",
          "axes.labelcolor": "white",  # no labels in this example
          "axes.grid": "True",
          "grid.linestyle": "--",      # {'-', '--', '-.', ':', '', (offset, on-off-seq), ...}
          "xtick.color": "white",
          "ytick.color": "white",
          "grid.color": "lightgray",
          "figure.facecolor": "black", # color surrounding the plot
          "figure.edgecolor": "black",
      })
      
      fig = pylab.figure(figsize=[4, 2], # Inches
                         dpi=100)        # 100 dots per inch, so the resulting buffer is 400x200 pixels
      fig.patch.set_alpha(0.1)           # make the surrounding of the plot 90% transparent to show what it does
      
      ax = fig.gca()
      ax.plot([1, 2, 4])
      
      canvas = agg.FigureCanvasAgg(fig)
      canvas.draw()
      renderer = canvas.get_renderer()
      raw_data = renderer.buffer_rgba()
      
      pygame.init()
      window = pygame.display.set_mode((600, 210), DOUBLEBUF)
      screen = pygame.display.get_surface()
      
      size = canvas.get_width_height()
      surf = pygame.image.frombuffer (raw_data, size, "RGBA")
      
      bg_color = (255, 0, 0)   # fill red as background color
      screen.fill(bg_color)
      screen.blit(surf, (100, 5)) # x, y position on screen
      pygame.display.flip()
      
      stop = False
      while not stop:
          for event in pygame.event.get():
              if event.type == pygame.QUIT:
                  stop = True
          pygame.time.Clock().tick(30)  # Avoid 100% CPU usage
      

      【讨论】:

      • 非常感谢!!!!
      • 这可行,但由于画布到缓冲区的转换,在超过 200 点时速度非常慢。有没有更直接的方法来加载 pygame.image 中的无花果?
      • 我投入了很多时间试图提高性能,但没有成功。具有更多 mathplotlib+pygame 知识的人可能仍会改进它。我想说的是,我的尝试也遇到了这个问题。
      【解决方案3】:

      我今天整天都在尝试扩展@furas 的答案,以摆脱那个破烂的白色背景。为了后代,我会把它放在这里。使用他的答案,但是将这两行替换为使用 alpha 分量,因此背景是透明的:

      raw_data = renderer.buffer_rgba ()
      surf     = pygame.image.frombuffer (raw_data, size, "RGBA")
      

      我还用图调整了一些设置:

      dims = pygame2matplotlib (w, h)
      fig  = plt.figure (**dims, facecolor='none', edgecolor='none')
      fig.patch.set_visible (False)
      

      【讨论】:

      • 您从哪里获取pygame2matplotlib 和plt?你能发布你的完整代码吗?作为一个 pygame 和 matplotlib 新手,我在编译你的添加时遇到了问题。
      【解决方案4】:

      matplotlib 默认使用tkinter 来显示图形。它也可以使用PyQt 或wxPython - 它们被称为"backends" - 但它没有使用PyGame 作为后端的方法。

      我发现(使用 Google)的唯一信息是 example in PyGame wiki

      它将 matplotlib 图形渲染为位图,然后将此位图转换为字符串,该字符串可用于创建带有图像的Surface。

      import matplotlib
      matplotlib.use("Agg")
      
      import matplotlib.backends.backend_agg as agg
      
      
      import pylab
      
      fig = pylab.figure(figsize=[4, 4], # Inches
                         dpi=100,        # 100 dots per inch, so the resulting buffer is 400x400 pixels
                         )
      ax = fig.gca()
      ax.plot([1, 2, 4])
      
      canvas = agg.FigureCanvasAgg(fig)
      canvas.draw()
      renderer = canvas.get_renderer()
      raw_data = renderer.tostring_rgb()
      
      import pygame
      from pygame.locals import *
      
      pygame.init()
      
      window = pygame.display.set_mode((600, 400), DOUBLEBUF)
      screen = pygame.display.get_surface()
      
      size = canvas.get_width_height()
      
      surf = pygame.image.fromstring(raw_data, size, "RGB")
      screen.blit(surf, (0,0))
      pygame.display.flip()
      
      crashed = False
      while not crashed:
          for event in pygame.event.get():
              if event.type == pygame.QUIT:
                  crashed = True
      

      我不会使用 matplotlib 来创建图形 - 特别是它不是交互式的。在 PyGame 中创建自己的图表很容易。

      【讨论】:

      • 如何在 pygame 中创建自己的图形?感谢您的快速回复 - 我也在谷歌上找到了这个,但老实说我不明白它是如何工作的。谢谢你的解释。
      • 您可以使用pygame.draw.rect() 来绘制条形图。 PyGame 有其他方法来绘制对象和文本。您必须单独绘制每个元素,但您可以控制它,它可以是动画的或交互式的。
      • 用 PyGame 查看未来的 GUI - 有动画条 - youtu.be/_5qFQvuHrXg
      • Future GUI 示例的代码。
      • 我知道这是旧的,但我会添加我认为重要的区别:Pygame 还没有良好的抗锯齿绘图功能。这使得线条和其他形状看起来非常锯齿状,并且通常不像 matplotlib 可以生成的那样干净。我正在处理对应用程序的类似需求。使用 pygame 编码后,我决定研究使用 matplotlib 渲染到缓冲区并通过 pygame 显示图形。这种方式产生的线条和其他形状的平滑度,据我所知是pygame无法比拟的。顺便说一句,我将其用于模拟,而不是游戏。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-04
      • 1970-01-01
      • 2014-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多