Seaborn: title and subtitle placement

2024/9/16 23:36:07

H all,

I'd like to create a scatterplot with a title, subtitle, colours corresponding to a specific variable and size corresponding to another variable. I want to display the colour legend but not the size. Here is what I have so far:

# imports
import seaborn as sns
import matplotlib
from matplotlib import style
import matplotlib.pyplot as plt# parameters
matplotlib.rcParams['font.family'] = "roboto"
style.use('fivethirtyeight')# load data
iris = sns.load_dataset('iris')# plot
ax = sns.relplot('sepal_length','sepal_width',hue='species',size='petal_width',alpha=0.75,kind="scatter",legend=False,data=iris
)# make adjustments
ax.set_axis_labels(x_var='Sepal Length', y_var='Sepal Width')
plt.text(x=4.7, y=4.7, s='Sepal Length vs Width', fontsize=16, weight='bold')
plt.text(x=4.7, y=4.6, s='The size of each point corresponds to sepal width', fontsize=8, alpha=0.75)
plt.show()

Output:

scatterplot

Here are my questions:

1) Is there a better way to set a subtitle? I tried this using ax.suptitle("blah", y=1.05) but it ends up sitting outside the scope of the figure. I don't like that I have to set x and y coordinates for my title/subtitle.

2) Is there a way for me to display the colour legend without showing the size legend? I would also like to be able to display this legend below the plot (or outside it). if you can answer that question, I'll change the title of this post, mark your answer as complete and create another question about the titles and subtitles

Many thanks!

Answer

Using scatterplot() makes it easier to manipulate the legend. If you use legend='brief then you'll get this legend:

enter image description here

You can get the artists and the labels used to create this legend using:

h,l = ax.get_legend_handles_labels()

since you only want the color info, and not the size, the solution is simply to recreate the legend using the first half of the artists

ax.legend(h[:4],l[:4])

Full code:

matplotlib.style.use('fivethirtyeight')
# load data
iris = sns.load_dataset('iris')# plot
fig, ax = plt.subplots(figsize=(7,5))
sns.scatterplot('sepal_length','sepal_width',hue='species',size='petal_width',alpha=0.75,legend='brief',data=iris,ax=ax
)# make adjustments
ax.set_xlabel('Sepal Length')
ax.set_ylabel('Sepal Width')ax.text(x=0.5, y=1.1, s='Sepal Length vs Width', fontsize=16, weight='bold', ha='center', va='bottom', transform=ax.transAxes)
ax.text(x=0.5, y=1.05, s='The size of each point corresponds to sepal width', fontsize=8, alpha=0.75, ha='center', va='bottom', transform=ax.transAxes)h,l = ax.get_legend_handles_labels()
ax.legend(h[:4],l[:4], bbox_to_anchor=(1.05, 1), loc=2)fig.tight_layout()
plt.show()

enter image description here

https://en.xdnf.cn/q/73043.html

Related Q&A

Calculate a rolling regression in Pandas and store the slope

I have some time series data and I want to calculate a groupwise rolling regression of the last n days in Pandas and store the slope of that regression in a new column.I searched the older questions an…

Python read microphone

I am trying to make python grab data from my microphone, as I want to make a random generator which will use noise from it. So basically I dont want to record the sounds, but rather read it in as a da…

How to tell pytest-xdist to run tests from one folder sequencially and the rest in parallel?

Imagine that I have test/unit/... which are safe to run in parallel and test/functional/... which cannot be run in parallel yet.Is there an easy way to convince pytest to run the functional ones sequen…

PyPDF4 - Exported PDF file size too big

I have a PDF file of around 7000 pages and 479 MB. I have create a python script using PyPDF4 to extract only specific pages if the pages contain specific words. The script works but the new PDF file,…

Jupyter install fails on Mac

Im trying to install Jupyter on my Mac (OS X El Capitan) and Im getting an error in response to:sudo pip install -U jupyterAt first the download/install starts fine, but then I run into this:Installing…

Python Error Codes are upshifted

Consider a python script error.pyimport sys sys.exit(3)Invokingpython error.py; echo $?yields the expected "3". However, consider runner.pyimport os result = os.system("python error.py&…

Running dozens of Scrapy spiders in a controlled manner

Im trying to build a system to run a few dozen Scrapy spiders, save the results to S3, and let me know when it finishes. There are several similar questions on StackOverflow (e.g. this one and this oth…

How to merge two DataFrame columns and apply pandas.to_datetime to it?

Im learning to use pandas, to use it for some data analysis. The data is supplied as a csv file, with several columns, of which i only need to use 4 (date, time, o, c). Ill like to create a new DataFr…

Breaking a parent function from within a child function (PHP Preferrably)

I was challenged how to break or end execution of a parent function without modifying the code of the parent, using PHPI cannot figure out any solution, other than die(); in the child, which would end …

Get absolute path of caller file

Say I have two files in different directories: 1.py (say, in C:/FIRST_FOLDER/1.py) and 2.py (say, in C:/SECOND_FOLDER/2.py).The file 1.py imports 2.py (using sys.path.insert(0, #path_of_2.py) followed,…