Home > Enterprise >  Matplotlib: How to get size of a figure within a window
Matplotlib: How to get size of a figure within a window

Time:03-24

Inputted x, y, and z coordinates will output three graphs: an x-z graph sliding along the y axis, an x-y graph sliding along the z axis, and a y-z graph sliding along the x axis. I position the lines based on the percent by which the user has slid its corresponding coordinate on the slider tool. See below (don't be alarmed by how the coronal and transverse views are switched):

Image

However, as you can see, the y-coordinate is low, so the line is out of the bounds of the figure. The issue is the lines are positioned relative to the window rather than relative to the plot. Therefore, I would like to get the size of the figure within the window to correct for this issue. I have not found any documentation on how to find the dimensions of a figure within a window as opposed to the whole window—how would I approach this? Thank you! See my code below to see how each individual plot is visualized:

fig = plt.figure(d 1, figsize = (maxX, maxY))
xCoord = -1
yCoord = -1
if d == 0:
    thisSlice = fData[newVoxel.s, :, :, 0]
    plt.title("Saggital")
    xCoord = newVoxel.t / maxT
    yCoord = newVoxel.c / maxC
elif d == 1:
    thisSlice = fData[:, newVoxel.t, :, 0]
    plt.title("Transverse")
    xCoord = newVoxel.s / maxS
    yCoord = newVoxel.c / maxC
elif d == 2:
    thisSlice = fData[:, :, newVoxel.c, 0]
    plt.title("Coronal")
    xCoord = newVoxel.s / maxS
    yCoord = newVoxel.t / maxT
artists.append(fig.add_artist(lines.Line2D([0, 1], [yCoord, yCoord])))
artists.append(fig.add_artist(lines.Line2D([xCoord, xCoord], [0, 1])))
plt.axis('off')
plt.imshow(thisSlice.T, cmap = 'inferno', origin = 'lower')

CodePudding user response:

It is possible to transform figure points into axis data; matplotlib has an entire framework dedicated to this. However, why make your life more difficult? I suggest structuring the figures differently around the axis limits of the plotted images:

import matplotlib.pyplot as plt

#random data
import numpy as np
rng = np.random.default_rng(123)
maxX = rng.integers(10, 20)
maxY = rng.integers(5, 10)
thisSlice = rng.random((maxX, maxY))


def define_figure(d, thisSlice): 
    fig = plt.figure(d 1, figsize=(maxX, maxY))
    ax = fig.add_subplot()
    artists = []

    my_title = ["Saggital", "Transverse", "Coronal"][d]
    ax.set_title(my_title)
    ax.axis('off')
    img = ax.imshow(thisSlice.T, cmap = 'inferno', origin = 'lower')

    view_x_max, view_y_max = thisSlice.shape
    viewlimits = [view_x_max, view_y_max]

    artists.append(ax.axhline(y=view_y_max//2, xmin=-10, xmax=10, clip_on = False))
    artists.append(ax.axvline(x=view_x_max//2, ymin=-10, ymax=10, clip_on = False))

    return fig, ax, img, artists, viewlimits
    
#create figure and capture essential figure elements you will need for later updates
current_figure, current_axis, current_image, current_lineartists, current_viewlimits = define_figure(1, thisSlice)
#now limit the slider range to integer values not exceeding current_viewlimits

#or update the image in axis if the corresponding slider is moved
def update_image(img_object, newimage):
    img_object.set_data(newimage.T)

plt.pause(5)
update_image(current_image, rng.random(thisSlice.shape))
plt.pause(5)

plt.show()
  • Related