Python matplotlib gets bounding box size

I am trying to draw a graph where each node is automatically placed one unit below its parent. Here is an example:

enter image description here

Each node represents some text surrounded by a bounding box, which may have a different size and may contain many values ​​(for example, field 3 is very long). I need to get the bottom coordinate of each node parent and draw a node 1 child below. However, my problem is that the reported coordinates of the bounding rectangles are incorrect. In the above example, I expect box 4 to be one lower than block 3, but the bottom coordinate of window 3 will be specified as -1.5 instead of -2.3. Box 4 is now too close to its parent. I am using Python 2.7.13. Here is my code:

import matplotlib.pyplot as plt #instantiate plot plt.axes() ax = plt.gca() ax.cla() #simple setup: draw some nodes at predefined positions t1 = ax.text(0, 0, '1', ha='center', va='top', color='black', bbox=dict(facecolor='#ccfff5', edgecolor='black',boxstyle='round,pad=0.5'),fontsize=8) t2 = ax.text(-1, -1, '2', ha='center', va='top', color='black', bbox=dict(facecolor='#ccfff5', edgecolor='black',boxstyle='round,pad=0.5'),fontsize=8) t3 = ax.text(1, -1, '3\n\nA\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM', ha='center', va='top', color='black', bbox=dict(facecolor='#ccfff5', edgecolor='black',boxstyle='round,pad=0.5'),fontsize=8) #draw edges between the nodes plt.plot([0, 0],[0,0], zorder=1, color='#404040', linewidth=1) plt.plot([0, -1],[0,-1], zorder=1, color='#404040', linewidth=1) plt.plot([0, 1],[0,-1], zorder=1, color='#404040', linewidth=1) #Obtain the dimensions of box 3 so that we can place box 4 properly underneath box 3 canvas = ax.figure.canvas r = canvas.get_renderer() transf = ax.transData.inverted() bb = t3.get_window_extent(renderer = r) bb_datacoords = bb.transformed(transf) #The y0 coordinate of box 3 is not the expected bottom print "box coordinates: ", bb_datacoords #Bbox(x0=0.978654233871, y0=-1.5130952381, x1=1.02134576613, y1=-1.0) print "bottom of box 3: ", bb_datacoords.y0 #-1.5130952381 #define the top y coordinate of box 4 newY = (bb_datacoords.y0 - 1) print "top position of box 4: ", newY #-2.5130952381 #the bottom coordinate of box 3 newPreviousY = bb_datacoords.y0 print "bottom position of box 3: ", newPreviousY #-1.5130952381 #Add box 4 1 unit below box 3 t4 = ax.text(1, newY, '4', ha='center', va='top', color='black', bbox=dict(facecolor='#ccfff5', edgecolor='black',boxstyle='round,pad=0.5'),fontsize=8) plt.plot([1, 1],[newPreviousY,newY], zorder=1, color='#404040', linewidth=1) plt.show() 

I managed to get closer to solving this problem by disabling the axis limits before drawing anything on the chart and setting manual limits as:

 plt.xlim(-1, 1) plt.ylim(-6, 1) plt.autoscale(False) 

Box 4 then is still not drawn exactly 1 unit below window 3 (but I think these are problems with filling), but it works almost as expected. However, setting the axis limits in advance is not ideal, because I need to automatically draw trees and I don’t know what borders of the graph should be at this point.

How can I get the correct bottom coordinate of each window and place a new block one unit lower?

+5
source share

Source: https://habr.com/ru/post/1264338/


All Articles