I would like to know how can I make a squared plot using matplotlib
when I have 2 y-axis. Here is an example:
import matplotlib.pyplot as plt
import seaborn as sns
gammas = sns.load_dataset("gammas")
sns.set(context="paper", palette="colorblind", style="ticks")
fig, ax1 = plot.subplots()
sns.tsplot(gammas[(gammas["ROI"] == "IPS")].reset_index(), time="timepoint", unit="subject", value="BOLD signal", ci=95, color="#4477AA", legend=False, ax=ax1)
ax1.set_xlabel("Timepoint")
ax1.set_ylabel("BOLD signal (1)")
ax1.spines["top"].set_visible(False)
ax1.tick_params(top='off')
ax2 = ax1.twinx()
ax2.yaxis.tick_right()
ax2.yaxis.set_label_position("right")
sns.tsplot(gammas[(gammas["ROI"] == "AG")].reset_index(), time="timepoint", unit="subject", value="BOLD signal", ci=95, color="#CC6677", legend=False, ax=ax2)
ax2.set_ylabel("BOLD signal (2)")
ax2.spines["top"].set_visible(False)
ax2.tick_params(top='off')
# Set legend #
ax2.legend([ax1.get_lines()[0], ax2.get_lines()[0]], ["IPS", "AG"], loc='upper left')
plt.show()
As you can see, the resulting plot is not squared:
So far, I have tried the following before the plt.show()
command:
ax1.set_aspect(1. / ax1.get_data_ratio())
ax1.set_aspect(1. / ax1.get_data_ratio())
and ax2.set_aspect(1. / ax2.get_data_ratio())
fig.set_size_inches(fig.get_size_inches()[0], fig.get_size_inches()[0])
to force the image to be squared, but I have measured the x and y axis with a ruler and their size is different (by a slight difference)The data I am using has 2 different scales: the 1st y-axis ranges from 0 to 250 while the 2nd one ranges from 0 to 100 (this is why I thought about multiplying all values used in ax2 by a factor of 2.5). I am sure there is something obvious that I am not seeing, so thank you in advance.
It's not entirely clear whether you want your axes to be of equal length, or whether you want the scaling on your axes to be equal.
To get a square aspect ratio, I created a figure with a square dimension fig = plt.figure(figsize=(5,5))
this is enough to get axes that are the same length.
To get the same scaling on all axes, I added the set_scaling()
instructions
import matplotlib.pyplot as plt
import seaborn as sns
gammas = sns.load_dataset("gammas")
sns.set(context="paper", palette="colorblind", style="ticks")
fig = plt.figure(figsize=(5,5))
ax1 = fig.add_subplot(111)
sns.tsplot(gammas[(gammas["ROI"] == "IPS")].reset_index(), time="timepoint", unit="subject", value="BOLD signal", ci=95, color="#4477AA", legend=False, ax=ax1)
ax1.set_xlabel("Timepoint")
ax1.set_ylabel("BOLD signal (1)")
ax1.spines["top"].set_visible(False)
ax1.tick_params(top='off')
ax2 = ax1.twinx()
ax2.yaxis.tick_right()
ax2.yaxis.set_label_position("right")
sns.tsplot(gammas[(gammas["ROI"] == "AG")].reset_index(), time="timepoint", unit="subject", value="BOLD signal", ci=95, color="#CC6677", legend=False, ax=ax2)
ax2.set_ylabel("BOLD signal (2)")
ax2.spines["top"].set_visible(False)
ax2.tick_params(top='off')
# Set legend #
ax2.legend([ax1.get_lines()[0], ax2.get_lines()[0]], ["IPS", "AG"], loc='upper left')
# set the aspect ratio so that the scaling is the same on all the axes
ax1.set_aspect('equal')
ax2.set_aspect('equal')