How can I position xlabel on top of the plot using something else than "tick_top" - that adds a tick to the x label, and I don't want it.
xlabel on the bottom with no tick:
code:
import numpy as np; np.random.seed(0)
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
uniform_data = np.random.rand(10, 12)
ax = sns.heatmap(uniform_data, vmin=0, vmax=1)
plt.yticks(rotation=0)
plt.show()
xlabel on top but with tick:
code:
import numpy as np; np.random.seed(0)
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
uniform_data = np.random.rand(10, 12)
ax = sns.heatmap(uniform_data, vmin=0, vmax=1)
plt.yticks(rotation=0)
ax.xaxis.tick_top() # x axis on top
ax.xaxis.set_label_position('top')
plt.show()
Try this:
plt.tick_params(axis='both', which='major', labelsize=10, labelbottom = False, bottom=False, top = False, labeltop=True)
the parameter top=False means no ticks. :)
Ok finally found.
Needs a
ax.tick_params(length=0)
Related
I am trying to highlight minimum values of each row using the same color:
For instance, the first row minimum is 0.3. I want to highlight it with blue color. Similarly, for the second row, 0.042 and so on.
Here's the code.
import numpy as np
import seaborn as sns
import matplotlib.pylab as plt
from matplotlib.patches import Rectangle
Pe = np.random.rand(5,5)
annot=True
fig, ax1 = plt.subplots(1)
ax1 = sns.heatmap(Pe, linewidth=0.5,ax=ax1,annot=annot)
You could loop through the rows, find the index of the minimum, and draw a rectangle there. Setting clip_on=False prevents that the rectangles would be clipped by the border.
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
Pe = np.random.rand(5, 5)
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(10, 4))
sns.set_style('white')
sns.heatmap(Pe, linewidth=0.5, annot=True, ax=ax1)
for ind, row in enumerate(Pe):
min_col = np.argmin(row)
ax1.add_patch(plt.Rectangle((min_col, ind), 1, 1, fc='none', ec='skyblue', lw=5, clip_on=False))
sns.heatmap(Pe, mask=Pe != Pe.min(axis=1, keepdims=True), annot=True, lw=2, linecolor='black', clip_on=False,
cmap=ListedColormap(['skyblue']), cbar=False, ax=ax2)
plt.tight_layout()
plt.show()
PS: To create animations, the Celluloid library is a lightweight option:
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import seaborn as sns
import numpy as np
from celluloid import Camera
Pe = np.random.rand(5, 5)
fig, ax1 = plt.subplots()
camera = Camera(fig)
sns.set_style('white')
row_array = np.arange(Pe.shape[0]).reshape(-1, 1)
for row in range(Pe.shape[0]):
sns.heatmap(Pe, mask=(Pe != Pe.min(axis=1, keepdims=True)) | (row < row_array),
annot=True, lw=2, linecolor='black', clip_on=False,
cmap=ListedColormap(['skyblue']), cbar=False, ax=ax1)
camera.snap()
animation = camera.animate(interval=800)
animation.save('animation.gif')
plt.show()
For more complicated animations, matplotlib's animation API can be considered.
I want to change the color of lineborder of violinplots.
I can set lines.linewidth to 0 but I want to show borders not to hide them. How to change the color of the border?
sns.set_context("paper", rc={"lines.linewidth": 0.8})
My code is as follows:
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib import style
import pandas as pd
import numpy as np
datasets = pd.read_csv("merged.csv", index_col=0);
df = datasets
df.protocol = df.protocol.astype(str)
f, ax = plt.subplots(figsize=(18, 6))
sns.violinplot(x="time",
y="values",
hue="protocol",
data=df,
bw=.5,
scale="count"
)
sns.despine(left=True)
f.suptitle('Title', fontsize=22, fontweight='bold')
ax.set_xlabel("Time",size = 16,alpha=0.7)
ax.set_ylabel("Values",size = 16,alpha=0.7)
ax.set_xticklabels(df.qber, rotation=90)
ax.grid(True)
plt.legend(loc='upper right')
plt.grid(linestyle='--', alpha=0.7)
fig = ax.get_figure()
fig.savefig('time_v.pdf', bbox_inches='tight')
Thank you!
this should be very close to what you're looking for:
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib import style
import pandas as pd
import numpy as np
def patch_violinplot(palette, n):
from matplotlib.collections import PolyCollection
ax = plt.gca()
violins = [art for art in ax.get_children() if isinstance(art, PolyCollection)]
colors = sns.color_palette(palette, n_colors=n) * (len(violins)//n)
for i in range(len(violins)):
violins[i].set_edgecolor(colors[i])
datasets = pd.read_csv("merged.csv", index_col=0);
df = datasets
df.protocol = df.protocol.astype(str)
num_cols = df['protocol'].nunique()
f, ax = plt.subplots(figsize=(18, 6))
sns.violinplot(x="time",
y="values",
hue="protocol",
data=df,
bw=.5,
scale="count",
palette="deep"
)
patch_violinplot("deep", num_cols)
sns.despine(left=True)
f.suptitle('Title', fontsize=22, fontweight='bold')
ax.set_xlabel("Time",size = 16,alpha=0.7)
ax.set_ylabel("Values",size = 16,alpha=0.7)
ax.set_xticklabels(df.qber, rotation=90)
ax.grid(True)
plt.legend(loc='upper right')
plt.grid(linestyle='--', alpha=0.7)
fig = ax.get_figure()
fig.savefig('time_v.pdf', bbox_inches='tight')
The patch_violin function came from here.
I'm trying to completely remove the y-axis from a plot in created with matplotlib. The code I'm using is:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from scipy.stats import skewnorm
f = plt.figure(figsize=(8,4))
ax = f.add_subplot(111)
colors = ["windows blue", "faded green", "dusty purple"]
colors = sns.xkcd_palette(colors)
b = 4
for j, a in enumerate([(0, 'No skew'), (b, 'Positive skew'), (-b, 'Negative skew')]):
x = np.linspace(skewnorm.ppf(0.001, a[0]), skewnorm.ppf(0.999, a[0]), 100)
y = skewnorm.pdf(x, a[0])
plt.plot(x, y, label=a[1], color=colors[j])
ax.yaxis.set_visible(False)
plt.legend(loc=2)
sns.despine()
This produces a plot with the y-axis ticks removed, but the axis itself still visible (shown below). How can I turn this axis off entirely?
You need to explicitly provide the left or bottom parameter to despine with sns.despine. By default, only right and top axes are removed.
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from scipy.stats import skewnorm
f = plt.figure(figsize=(8,4))
ax = f.add_subplot(111)
colors = ["windows blue", "faded green", "dusty purple"]
colors = sns.xkcd_palette(colors)
b = 4
for j, a in enumerate([(0, 'No skew'), (b, 'Positive skew'), (-b, 'Negative skew')]):
x = np.linspace(skewnorm.ppf(0.001, a[0]), skewnorm.ppf(0.999, a[0]), 100)
y = skewnorm.pdf(x, a[0])
ax.plot(x, y, label=a[1], color=colors[j])
ax.yaxis.set_visible(False)
plt.legend(loc=2)
sns.despine(left=True)
One can also remove the axis and the spine directly with matplotlib.
If you remove the xticks or yticks by
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
the spines are still visible. If you want to turn off also the spines, so having no axis at all, you can use:
ax.spines['bottom'].set_visible(False)
ax.spines['left'].set_visible(False)
And if you want to turn everything off at once, use:
ax.axis("off")
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
How can I keep seaborn.despine from putting both of my y-scales onto the left side of my plot?
The best I've come up with so far is:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
sns.set_style("white")
fig, ax = plt.subplots()
ax.plot(np.random.rand(10))
ax2 =ax.twinx()
ax2.plot(100*np.random.rand(10))
sns.despine(ax=ax, right=True, left=True)
sns.despine(ax=ax2, left=True, right=False)
But any other combination will either not despine the y-axes or put the right axis onto the left.
Output of the above: (desired output has no spines, just numbers on left and right)
I guess that's what you want then.
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
sns.set_style("white")
fig, ax = plt.subplots()
ax.plot(np.random.rand(10))
ax2 =ax.twinx()
ax2.plot(100*np.random.rand(10))
sns.despine(ax=ax, right=True, left=True)
sns.despine(ax=ax2, left=True, right=False)
ax2.spines['right'].set_color('white')