I have a scatterplot that consists of multiple subplots using seaborn's "col" and "row" feature, eg
sns.relplot(data=data,x="YEL-HLog",y="FSC-HLog",hue="Treatment",row="Fraction",col="Biounit",s=1)
I want to overlay a line over parameter x on each of those subplots. The kicker is that line differs for different columns. To that extent, I used the follwoing code:
sns.relplot(data=new,x="Threshold",y="FSC-HLog",hue="Treatment",row="Fraction",col="Biounit",s=1)
"New" is the same dataframe but with the column "Threshold" inserted. So everything is the same, except the x value.
However, this just gives me two different graphs. How do I combine the two to show on the same plot?
Every time a figure-level function such assns.relplot
is called, a new figure is created. relplot
returns a FacetGrid
containing the information of how the subplots are created. You can loop through g.axes
and draw a line on each of them.
Here is an example:
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
N = 2000
data = pd.DataFrame({"YEL-HLog": np.random.rand(N),
"FSC-HLog": np.random.rand(N),
"Treatment": np.random.choice(['A', 'B', 'C'], N),
"Fraction": np.random.choice(['Fr1', 'Fr2'], N),
"Biounit": np.random.choice(['Unit1', 'Unit2', 'Unit3'], N)})
threshold_dict = {('Fr1', 'Unit1'): 0.1, ('Fr1', 'Unit2'): 0.2, ('Fr1', 'Unit3'): 0.3,
('Fr2', 'Unit1'): 0.6, ('Fr2', 'Unit2'): 0.7, ('Fr2', 'Unit3'): 0.8}
g = sns.relplot(data=data, x="YEL-HLog", y="FSC-HLog", hue="Treatment", row="Fraction", col="Biounit", height=3)
for row, row_name in enumerate(g.row_names):
for col, col_name in enumerate(g.col_names):
ax = g.axes[row, col]
threshold = threshold_dict[(row_name, col_name)]
ax.axvline(threshold, color='red', ls='--', lw=3)
g.fig.subplots_adjust(left=0.07, bottom=0.09)
plt.show()
It is quite unclear how the new
dataframe gets its values. It could be created from the threshold_dict
, but that seems like an unnecessary indirection. Just to be complete, in that case the code could look as follows:
new_df = data
new_df["Threshold"] = data.apply(lambda d: threshold_dict[(d['Fraction'], d['Biounit'])], axis=1)
for ...
for ...
threshold = new_df[(new_df["Fraction"] == row_name) & (new_df["Biounit"] == col_name)]["Threshold"].iloc[0]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.