【问题标题】:Combine multiple matplotlib figures into one将多个 matplotlib 图形合二为一
【发布时间】:2019-12-05 15:41:22
【问题描述】:

我有一个函数,它接受一个增强的 dicom 文件并执行以下操作:

  1. 使用 for 循环从 dicom 文件创建单个切片,然后将其索引到围绕一组六个斑点的较小数组中。
  2. 第二个 for 循环围绕六个斑点和一个背景绘制圆圈
  3. 显示带有绘制的所有圆圈和当前切片位置的图像。

当我调用该函数时,我可以创建多个以单独的图形显示的图像。那么,我怎样才能将所有这些数字合二为一呢?理想情况下,我想将它们显示在 3x3 网格中。

这是我当前的代码:

import matplotlib.pyplot as plt
import pydicom # Used for opening DICOM files
import numpy as np # General mathematical package
from pylab import text

# Import DICOM files
filename = "U:/File location" 
ds = pydicom.dcmread(filename)

# Speck Locations
centerSpeck = (1690, 1477)
centerSpeck2 = (100, 100)
twelveOclockSpeck = (45, 84)
twoOkclockSpeck = (66, 148)
tenOclockSpeck = (136, 147)
fiveOclockSpeck = (157, 82)
sevenOclockSpeck = (102, 41)
backgroundSignalValue = (71, 63)

speckLocations = np.array([centerSpeck2, twelveOclockSpeck, twoOkclockSpeck, fiveOclockSpeck, sevenOclockSpeck, tenOclockSpeck, backgroundSignalValue])

# Function that draws a circle around a given pixel
def drawCircle(arrayToPLot, zeroIndex, oneIndex, specks, r = 10):
    x = speckLocations[:,1] # get x axis variables from the speckLocations array
    y = speckLocations[:,0] # get y axis variables from the speckLocations array
    for i in range(zeroIndex,oneIndex,1): # For loop, note that the function range is: range(start, stop, step)
        tempIm = arrayToPLot.pixel_array[i,:,:].astype(float) # Get one slice as float
        slicedArray = tempIm[centerSpeck[0]-100:centerSpeck[0]+100, centerSpeck[1]-100:centerSpeck[1]+100].astype(float)
        for x,y in (speckLocations):
            plt.imshow(slicedArray, cmap='gray')
            circle = plt.Circle((y, x),r, fc='none', ec="red")
            plt.gca().add_patch(circle)    
            text(10, 180, i, fontsize=12, color='red') # Print the current slice on the image

        plt.show() # Plot each slice with circles drawn around all the specks and the background signal value location

#Call the function  
drawCircle(ds, 33, 34, speckLocations)

【问题讨论】:

  • 创建一个带有 3x3 子图的图形。然后将每个图像绘制到其中一个轴上。
  • 你能给我更多关于如何做到这一点的信息吗?我想出了如何用 3x3 子图创建一个图形,但无法将我的图形放入其中。我正在使用此页面中的说明:matplotlib.org/3.1.1/gallery/recipes/create_subplots.html.

标签: python numpy matplotlib dicom


【解决方案1】:

在下文中,我们将使用plt.subplots 方法生成axes 的图形和网格,人们将这些Matplotlib 对象理解为子图...

在 2D 网格上的迭代首先为您提供网格的一行,在该行上的第二次迭代为您提供单独的子图。当我们挑出一个轴时,是时候调用您的函数了(您有责任区分要绘制的数据,因为您的问题并不清楚您想要做什么),但需要一个额外的参数,即当前轴。

fig, ax_grid = plt.subplots(3,3)
for ax_row in ax_grid:
    for ax in ax_row:
        drawCircle(ax, ds, 33, 34, speckLocations)
plt.tight_layout()
plt.show()

最后我们展示了这个图,调用tight_layout来更好地安排子图。


当然我们要修改圆形绘图功能...首先我们将ax添加到参数列表中,接下来我们修改对plt方法的调用以使用ax对象的方法:

def drawCircle(ax, arrayToPLot, zeroIndex, oneIndex, specks, r = 10):
    ...
    ax.imshow(...)
    ...
    ax.add_patch(circle)
    ax.text(10, 180, i, fontsize=12, color='red')

【讨论】:

  • 您的回答帮助我更接近于我正在寻找的东西。然而,当我运行你给我的函数时,它会在每个窗口中绘制所有图片,然后将每张图片堆叠在一起。下图是我尝试将三张图片绘制到网格中时发生的情况:
  • 在我的分析器中,我写了 “你有责任区分要绘制的数据,因为你的问题并不清楚你想做什么” — 请写一个更好的问题也许你会得到更好的答案
  • 很抱歉这里的沟通不畅,但我确实在您的回答中看到了这一点,我试图了解如何区分要绘制的数据。所以,让我试着澄清一下我想要做什么。每次通过 drawCircle() 函数中的 for 循环,都会创建一张新图片,其中包含围绕斑点的圆圈和该图片的切片位置。我正在尝试将每张图片放入 3x3 网格并位于其自己的位置。我无法弄清楚为什么每张图片都被绘制了九次并堆叠在一起。你能帮我解决这个问题吗?
猜你喜欢
  • 2018-03-25
  • 1970-01-01
  • 2014-04-26
  • 2020-11-15
  • 1970-01-01
  • 2014-11-11
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
相关资源
最近更新 更多