sbslee / dokdo

A Python package for microbiome sequencing analysis with QIIME 2
https://dokdo.readthedocs.io
MIT License
42 stars 12 forks source link

Reverse order of legend for taxa_abundance_bar_plot #26

Closed mishkb closed 3 years ago

mishkb commented 3 years ago

Hi @sbslee

Are you able to advise how I can reverse the order of the legend of a taxa_abundance_bar_plot?

I've tried using:

handles, labels = ax2.get_legend_handles_labels() ax2.legend(handles[::-1], labels[::-1])

But this results in a missing legend.

Thanks!

sbslee commented 3 years ago

@mishkb,

As you can see below, your approach is correct and should work:

import dokdo
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
sns.set()

qzv_file = '/Users/sbslee/Desktop/dokdo/data/moving-pictures-tutorial/taxa-bar-plots.qzv'

fig, [ax1, ax2] = plt.subplots(1, 2, figsize=(20, 10))

dokdo.taxa_abundance_bar_plot(
    qzv_file,
    figsize=(10, 7),
    level=6,
    count=8,
    legend_short=True,
    ax=ax1
)

dokdo.taxa_abundance_bar_plot(
    qzv_file,
    figsize=(10, 7),
    level=6,
    count=8,
    legend_short=True,
    ax=ax2
)

handles, labels = ax2.get_legend_handles_labels()
ax2.legend(handles[::-1], labels[::-1])

plt.tight_layout()
plt.savefig('test.png')

test

Did you run the code that creates the new legend within the same cell or in a separate cell in Jupyter Notebook? They should be run together.

Hope this helps.

mishkb commented 3 years ago

Thanks @sbslee - I'm glad I was on the right track. I can get the reverse order to work as you have shown above, and legends are included in each plot.

But I can't get it to work when I'm using 'artist_kwargs=dict(legend_only=True, legend_loc='upper left') - to display the stacked bar chart with no legend and the legend only the second plot. I'm guessing there is a conflict with the artist?

sbslee commented 3 years ago

@mishkb,

Glad to hear things are working now!

Also, please note that the artist_kwargs argument has been completely deprecated in 1.11.0. As shown in the changelog and in this issue, the deprecation process began in 1.10.0 and was completed in 1.11.0. Therefore, you should not use the argument anymore.

You can still plot the legend only by following this tutorial. I just found that there is a typo ("We can ameliorate the issue by plotting the legend separately with legend_only=True."), but please ignore it :) I will fix this ASAP, but the code is still correct:

handles, labels = ax2.get_legend_handles_labels()

ax2.clear()
ax2.legend(handles, labels)
ax2.axis('off')

Finally, you can specify the location of a legend with:

ax.legend(..., loc='upper left')
mishkb commented 3 years ago

Thanks again @sbslee for your quick response. I knew i had read that you were deprecating kwargs but hadn't updated my file (you are making frequent updates - which is great!). I have the latest version of Dokdo. FYI - I also just found that 'plt.legend(bbox_to_anchor=(x0, y0)' or 'plt.legend(bbox_to_anchor=(x0, y0)' also works to move the legend out of the plot area. So you don't need to set-up two plots (one without legend, one without plot).

sbslee commented 3 years ago

@mishkb,

Glad to hear we are on the same page now. And yea, sorry about the frequent updates. I know it can be challenging for end users to stay up to date (been there, done that), but I believe those are worth it :) I promise future updates will be less disrupting for sure -- completely getting rid of artist_kwargs was a massive task and that's why it took two separate versions to accomplish it.

As for utilizing bbox_to_anchor, I am aware of that approach but personally I like to create a separate plot just for the legend because it allows me to precisely control the width and height ratios when I need to plot multiple plots within single figure. But if you have single bar chart and want to plot its legend separately, please be my guest and use bbox_to_anchor for that! Thanks for sharing your approach.