How to set a legend in an image heatmap (python)? - python

How can I move the vertical legend slightly upwards
(to the centre of rows)?
I need these very large letters
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
labels_raw=np.array([["98.75\n±0.50" ,"1.25\n±0.82"],[ "1.32\n±0.74", "98.68\n±0.74"]])
cm_raw=np.array([[98.75 ,1.25],[ 1.32, 98.68]])
sns.set(font_scale=2.5)
labels=labels_raw
cm=cm_raw
fig, ax = plt.subplots(figsize=(5,5))
target_names = ['test1','test2']
f=sns.heatmap(cm, annot=labels, fmt=':^', xticklabels=target_names,
yticklabels=target_names,annot_kws={"size": 25},cbar=False)
plt.show(block=False)
#plt.show()
fig=f.get_figure()

You can rotate your labels and set the vertical alignment to be center:
fig, ax = plt.subplots(figsize=(5,5))
target_names = ['test1','test2']
sns.heatmap(cm, annot=labels, fmt=':^', xticklabels=target_names,
yticklabels=target_names,annot_kws={"size": 25},cbar=False,ax=ax)
ax.set_yticklabels(target_names, rotation=0, fontsize="25", va="center")
Or this will keep the y-axis labels vertical:
sns.heatmap(cm, annot=labels, fmt=':^', xticklabels=target_names,
yticklabels=target_names,annot_kws={"size": 25},cbar=False,ax=ax)
ax.set_yticklabels(target_names, fontsize="25", va="center")

Related

Aligning colormap consistently with the plot

I am trying to align the matplotlib plot with its colorbar. However, when there is a tick on the top of the colormap, the figure itself shrinks a little bit:
Is there a way to equalize this distance (blue arrows) consistently?
For generating the plot, I am using following code:
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
ax.plot(...)
divider = make_axes_locatable(plt.gca())
cax = divider.append_axes('right', '5%', pad='3%')
sm = plt.cm.ScalarMappable(cmap=plt.get_cmap('viridis'),
norm=mpl.colors.Normalize(vmin=0, vmax=60))
sm.set_array([])
fig.colorbar(sm, cax=cax)
plt.tight_layout()
plt.savefig('pic.png', dpi=500)

How to put a colorbar in seaborn scatterplot legend

I have the next scatterplot
But i want to change the dots on the legend by continuos color map like this:
This is my code:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
sns.set_style("whitegrid")
gene_list = pd.read_csv('interseccion.csv', header=None)
glist = gene_list.squeeze().str.strip().tolist()
names = gp.get_library_name()
enr = gp.enrichr(gene_list= glist,
gene_sets=['KEGG_2019_Human'],
organism='Human', # don't forget to set organism to the one you desired! e.g. Yeast
description='KEGG',
# no_plot=True,
cutoff=0.5 # test dataset, use lower value from range(0,1)
)
resultados = enr.results.head(15)
resultados['-log10(FDR)'] = -np.log10(resultados['Adjusted P-value'])
resultados['Genes'] = resultados['Genes'].str.split(';')
resultados['Genes'] = resultados['Genes'].apply(lambda x: len(x))
g = sns.scatterplot(data=resultados, x="-log10(FDR)", y="Term", hue='-log10(FDR)', palette="seismic"
, size="Genes", sizes=(30, 300), legend=True)
g.legend(loc=6, bbox_to_anchor=(1, 0.5), ncol=1)
g.fig.colorbar()
plt.ylabel('')
plt.xlabel('-log10(FDR)')
When i try to put a color bar with the funcion plt.colorbar() is not possible
I customized the code in the official sample with the understanding that I wanted to add a legend and color bars to the Seaborn scatterplot. A colormap has been created to match the colors of the sample graph, but it can be drawn without problems by specifying the colormap name. The color bar is customized by getting its position and adjusting it manually in the legend. The height of the color bar is halved to match the legend.
import seaborn as sns
import matplotlib.pyplot as plt
tips = sns.load_dataset("tips")
fig, ax = plt.subplots()
g = sns.scatterplot(
data=tips, x="total_bill", y="tip", hue="size", size="size",
sizes=(20, 200), legend="full", ax=ax)
g.legend(loc='upper right', bbox_to_anchor=(1.2, 1.0), ncol=1)
norm = plt.Normalize(tips['size'].min(), tips['size'].max())
cmap = sns.cubehelix_palette(light=1, as_cmap=True)
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
cax = fig.add_axes([ax.get_position().x1+0.05, ax.get_position().y0, 0.06, ax.get_position().height / 2])
ax.figure.colorbar(sm, cax=cax)
plt.show()

Change position of marginal axis in seaborn jointplot

Seaborn by default plots the marginal distributions on the top and right of the main plot. Is it possible to change this location (e.g., to bottom and left)?
A minimal example, using the seaborn documentation:
tips = sns.load_dataset("tips")
g = sns.jointplot(x="total_bill", y="tip", data=tips)
gives...
It is a bit tedious, but you can adapt this example to your needs. It uses a make_axes_locatable divider. Changing this from top to bottom and from right to left is no problem, but then you need to change the labelling and ticks on all axes.
import seaborn as sns
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
tips = sns.load_dataset("tips")
x = tips["total_bill"]
y = tips["tip"]
fig, axScatter = plt.subplots(figsize=(5.5, 5.5))
fig.subplots_adjust(.1,.1,.9,.9)
axScatter.scatter(x, y)
divider = make_axes_locatable(axScatter)
axHistx = divider.append_axes("bottom", 1.2, pad=0.1, sharex=axScatter)
axHisty = divider.append_axes("left", 1.2, pad=0.1, sharey=axScatter)
# make some labels invisible
axHistx.tick_params(labelbottom=False, bottom=False,
left=False, labelleft=False, right=True, labelright=True)
axHisty.tick_params(labelleft=False, left=False,
bottom=False, labelbottom=False, top=True, labeltop=True)
axHistx.invert_yaxis()
axHisty.invert_xaxis()
axScatter.xaxis.tick_top()
axScatter.yaxis.tick_right()
axScatter.xaxis.set_label_position('top')
axScatter.yaxis.set_label_position('right')
axScatter.set(xlabel="Total Bill", ylabel="Tip")
axHistx.hist(x, bins=16, density=True)
axHisty.hist(y, bins=16, density=True, orientation='horizontal')
plt.show()

seaborn: how to make a tsplot square

I would like to create a tsplot, where the x and the y axis are the same length. in other words the aspect ratio of the graph should be 1.
this dos not work:
fig, ax = plt.subplots()
fig.set_size_inches(2, 2)
sns.tsplot(data=df, condition=' ', time='time', value='value', unit=' ', ax=ax)
You could change the aspect ratio of your plots by controlling the aspect
parameter of a matplotlib object as shown:
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
np.random.seed(22)
sns.set_style("whitegrid")
gammas = sns.load_dataset("gammas")
fig = plt.figure()
ax = fig.add_subplot(111, aspect=2) #Use 'equal' to have the same scaling for x and y axes
sns.tsplot(time="timepoint", value="BOLD signal", unit="subject",
condition="ROI", data=gammas, ax=ax)
plt.tight_layout()
plt.show()
A little more direct is ax.set_box_aspect(1)1

seaborn or matplotlib grid is covering the lines in the plot

Here is my (incomplete, I have note added the data itself) code, which produces a somewhat confusing plot, where one line is covered by the grid but the other not.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pylab
sns.set_context("poster",font_scale=fs)
sns.set_style("darkgrid") # No grid lines
# sns.set_style({'legend.frameon': 'True'})
sns.set_style({'xtick.major.size':'0.0'})
c1,c2 = sns.color_palette("hls",2)#sns.color_palette("colorblind", 2)
a = sns.color_palette("BuGn_r")
# runs_plot = pd.DataFrame(runs.values+8.5)
# Plot just first state trajectory
fig, ax1 = plt.subplots(1,sharey=True, sharex=True, figsize=(30,8))
ax1.plot((ground.values+6),label='Ground Truth',color=c1)
ax1.set_xlabel('Time [$s$]')
ax1.set_ylim(0,10)
ax1.set_ylabel('State [$\#$]')
for tl in ax1.get_yticklabels():
tl.set_color(c1)
ax2 = ax1.twinx()
ax2.plot(0.4*signal_syn.values+1,color=c2,label='Emission Signal')
ax2.set_ylabel('Observations')
ax2.set_ylim(0,10)
# ax2.set_axisbelow(True)
for tl in ax2.get_yticklabels():
tl.set_color(c2)
# ask matplotlib for the plotted objects and their labels
lines, labels = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(lines + lines2, labels + labels2,ncol=5,loc='upper center', bbox_to_anchor=(0.5, -0.2))
plt.show()
which produces
now and you can probably see, that for the "Ground Truth" the line is covered by the 'darkgrid' option of the seaborn (which produces a white grid as seen above). Now for some reason the grid is not above the emission signal but only the ground truth.
Any ideas for why this might be?
So this is what I ended up doing, it is probably more of a hack than an actual solution, but it works. I just moved the plotting elements so that they're all plotted above the grid.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pylab
sns.set_context("poster",font_scale=fs)
sns.set_style("darkgrid") # No grid lines
# sns.set_style({'legend.frameon': 'True'})
sns.set_style({'xtick.major.size':'0.0'})
c1,c2 = sns.color_palette("hls",2)#sns.color_palette("colorblind", 2)
a = sns.color_palette("BuGn_r")
# runs_plot = pd.DataFrame(runs.values+8.5)
# Plot just first state trajectory
fig, ax1 = plt.subplots(1,sharey=True, sharex=True, figsize=(30,8))
ax1.set_xlabel('Time [$s$]')
ax1.set_ylim(0,10)
ax1.set_ylabel('State [$\#$]')
for tl in ax1.get_yticklabels():
tl.set_color(c1)
ax2 = ax1.twinx()
ax2.plot((ground.values+6),label='Ground Truth',color=c1)
ax2.plot(0.4*signal_syn.values+1,color=c2,label='Emission Signal')
ax2.set_ylabel('Observations')
ax2.set_ylim(0,10)
# ax2.set_axisbelow(True)
for tl in ax2.get_yticklabels():
tl.set_color(c2)
# ask matplotlib for the plotted objects and their labels
lines, labels = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(lines + lines2, labels + labels2,ncol=5,loc='upper center', bbox_to_anchor=(0.5, -0.2))
plt.show()
Seems like the answer is in this question:
Matplotlib: draw grid lines behind other graph elements
And it is basically: Axis.set_axisbelow(True)

Categories