0

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: enter image description here

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())
  • scaling the data values used in ax2 so they adjust in magnitude to the values in ax1
  • 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.

1 Answer 1

2

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.

enter image description here

To get the same scaling on all axes, I added the set_scaling() instructions

enter image description here

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')
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.