3

I want to make x and y axes be of equal lengths (i.e the plot minus the legend should be square ). I wish to plot the legend outside (I have already been able to put legend outside the box). The span of x axis in the data (x_max - x_min) is not the same as the span of y axis in the data (y_max - y_min).

This is the relevant part of the code that I have at the moment:

plt.legend(loc='center left', bbox_to_anchor=(1, 0.5), fontsize=15 )
plt.axis('equal')
plt.tight_layout()

The following link is an example of an output plot that I am getting : plot

How can I do this?

user10853036
  • 125
  • 1
  • 8

2 Answers2

6

Would plt.axis('scaled') be what you're after? That would produce a square plot, if the data limits are of equal difference.

If they are not, you could get a square plot by setting the aspect of the axes to the ratio of xlimits and ylimits.

import numpy as np
import matplotlib.pyplot as plt

fig, (ax1, ax2) = plt.subplots(1,2)

ax1.plot([-2.5, 2.5], [-4,13], "s-")
ax1.axis("scaled")

ax2.plot([-2.5, 2.5], [-4,13], "s-")
ax2.set_aspect(np.diff(ax2.get_xlim())/np.diff(ax2.get_ylim()))

plt.show()

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • Thanks for your answer. Will it matter if the legend is outside of the plot? I will like to have the part of the plot which is without the legend be a square (I will like to have the legend besides this square plot). In my case, the data limits are not of equal difference. – user10853036 Jan 07 '19 at 21:51
  • It shouldn't matter if there is another subplot, or a legend next to the plot for this to work. I'd say try it out and see if you're happy with the result, else come back and explain any further problem. – ImportanceOfBeingErnest Jan 07 '19 at 21:53
  • Thanks for your answer. I tried it. It works, but there is this one issue - the sides of the plot get cut (this is with me using `plt.tight_layout()`. Here is the plot that I am getting after using the above suggestions. ( https://i.stack.imgur.com/sn6zj.png ) How can I not have the sides of the figure cut? – user10853036 Jan 07 '19 at 22:05
  • That shouldn't happen. Did you call tight_layout before setting the aspect? – ImportanceOfBeingErnest Jan 07 '19 at 22:23
  • I called tight_layout after setting the aspect. I don't have subplots, so I tried this method which is based on your suggestion. This is what I am doing in the relevant section of the code: **1st line:** `axes = plt.gca()` , **2nd line:** `axes.set_aspect( np.diff(axes.get_xlim())/np.diff(axes.get_ylim()) )` , **3rd line :** `plt.tight_layout()` , **4th line:** `plt.savefig('filename.png')` – user10853036 Jan 07 '19 at 22:26
  • I think I would need a verifiable example ([mcve]) to figure out what's wrong. – ImportanceOfBeingErnest Jan 07 '19 at 22:28
1

One option you have to is manually set the limits, assuming that you know the size of your dataset.

axes = plt.gca()
axes.set_xlim([xmin,xmax])
axes.set_ylim([ymin,ymax])

A better option would be to iterate through your data to find the maximum x- and y-coordinates, take the greater of those two numbers, add a little bit more to that value to act as a buffer, and set xmax and ymax to that new value. You can use a similar method to set xmin and ymin: instead of finding the maximums, find the minimums.

To put the legend outside of the plot, I would look at this question: How to put the legend out of the plot

nschmeller
  • 79
  • 1
  • 2
  • 9
  • I have already been able to put legend outside the box (The figure shows as much). The span of `x axis` in the data (`x_max - `x_min) is not the same as the span of `y axis` in the data (`y_max - `y_min). The only thing I want is to make x and y axes be of equal lengths (i.e the plot minus the legend should be square ). – user10853036 Jan 07 '19 at 21:03
  • Unless I'm misunderstanding something, I think you should be able to do what I described above. Let me know if it doesn't work – nschmeller Jan 07 '19 at 21:13
  • Nicholas: Thanks for your help. I really appreciate it. Unfortunately, it doesn't seem to work. I tried your suggestion. This is what I tried: plt.legend(loc='center left', bbox_to_anchor=(1, 0.5), fontsize=15 ) axes = plt.gca() xmin = np.min( XX[ : , 0 ] ) xmax = np.max( XX[ : , 0 ] ) ymin = np.min( XX[ : , 1 ] ) ymax = np.max( XX[ : , 1 ] ) axes.set_xlim([xmin,xmax]) axes.set_ylim([ymin,ymax]) – user10853036 Jan 07 '19 at 21:41