This question already has answers here:
How to add axis offset in matplotlib plot?
(2 answers)
Closed 4 years ago.
I am plotting two seaborn categorical plots (pointplot and swarmplot) on top of each other and just can't figure out how I can change the x axis position of one of them (i.e. the swarm plot in my particular case) so that instead of overlapping the plots are 'side by side' (i.e. ideally I want to have the individual data points to the right of the mean and ci).
Here's the code to produce the plot:
import seaborn as sns
# set style and font size
sns.set(style='white', rc={'figure.figsize':(6,6)}, font_scale=1.3)
# plot means as points with confidence intervals
a = sns.pointplot(x='Group',
y='RT',
data=data,
estimator= np.mean,
capsize=.2,
join=False,
color='black',
size=12)
# plot individual data points as swarmplot
b = sns.swarmplot(x='Group',
y='RT',
data=data,
size=8,
alpha=0.8)
You can feed the axis handle to the sns.
I am not sure whether this is what do you want!
import seaborn as sns
sns.set(style="whitegrid")
tips = sns.load_dataset("tips")
fig,ax =plt.subplots(1,2,figsize=(15,7))
sns.swarmplot(x="day", y="total_bill", data=tips,
ax= ax[1])
sns.pointplot(x='day',
y='total_bill',
data=tips,
estimator= np.mean,
capsize=.2,
join=False,
color='black',
size=12,ax=ax[0])
Related
I am trying to plot a kde plot in seaborn using the histplot function, and removing later the bars of the histogram in the following way (see last part of the accepted answer here):
fig, ax = plt.subplots()
sns.histplot(data, kde=True, binwidth=5, stat="probability", label='data1', kde_kws={'cut': 3})
The reason for using histplot instead of kdeplot is that I need to set a specific binwidth. The problem I have that I cannot print out the legend, meaning that
ax.legend(loc='best')
does nothing, and I receive the following message: No handles with labels found to put in legend.
I have also tried with
handles, labels = ax.get_legend_handles_labels()
plt.legend(handles, labels, loc='best')
but without results. Does anybody have an idea of what is going on here? Thanks in advance!
You can add the label for the kde line via the line_kws={'label': ...} parameter.
sns.kdeplot can't be used directly, because currently the only option is the default scaling (density).
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
data = np.random.normal(0.01, 0.1, size=10000).cumsum()
ax = sns.histplot(data, kde=True, binwidth=5, stat="probability", label='data1',
kde_kws={'cut': 3}, line_kws={'label': 'kde scaled to probability'})
ax.containers[0].remove() # remove the bars of the histogram
ax.legend()
plt.show()
This question already has answers here:
Draw a line at specific position/annotate a Facetgrid in seaborn
(5 answers)
Closed 1 year ago.
I want to add an axis line to my plot. I've tried other functions to set tick but it didn't work.
warnings.filterwarnings('ignore')
xvalues = np.arange(2)
# Graph - Grouped by class, survival and sex
r = sns.factorplot(x="Sex", y="Survived", col="Pclass", data=titanicData_clean,
saturation=.5, kind="bar", ci=None, size=5 ,aspect=.8)
r.fig.suptitle('class, survival and sex')
r.fig.subplots_adjust(top=0.9)
plt.xticks(xvalues)
plt.show()
# Fix up the labels
(r.set_axis_labels('', 'Survival Rate')
.set_titles("Class {col_name}")
.set(ylim=(0, 1))
.despine(left=True, bottom=True));
I don't know what kind of line you want. I will use the horizontal line as an example, and answer with examples of drawing individual lines on subplots and drawing a unified line.
The positions of the lines are appropriate, so please replace them with your own data.
import seaborn as sns
titanicData_clean = sns.load_dataset("titanic")
# warnings.filterwarnings('ignore')
xvalues = np.arange(2)
# Graph - Grouped by class, survival and sex
r = sns.catplot(x="sex", y="survived", col="pclass", data=titanicData_clean,
saturation=.5, kind="bar", ci=None, height=5 ,aspect=.8)
r.fig.suptitle('class, survival and sex')
r.fig.subplots_adjust(top=0.9)
plt.xticks(xvalues)
ax1,ax2,ax3 = r.axes[0]
# Fix up the labels
(r.set_axis_labels('', 'Survival Rate')
.set_titles("Class {col_name}")
.set(ylim=(0, 1))
.despine(left=True, bottom=True))
# When drawing individual horizontal lines
ax1.axhline(0.4, ls='--')
ax2.axhline(0.2, ls='--')
ax3.axhline(0.2, ls='--')
# To draw a horizontal line in a unified manner
r.map(plt.axhline, y=0.5,ls='-', c='r')
plt.show()
This question already has answers here:
Getting empty tick labels before showing a plot in Matplotlib
(2 answers)
Closed 2 years ago.
I am seeking a better understanding of python plotting routines in pandas/matplotlib that cause xticklabels to disappear when formatting is attempted. To demonstrate, here is some basic code to recreate the problem:
#Create dummy variables x and y in a dataframe and plot in a scatter plot with the xticklabels rotated 35 degrees
data={'x':[1111,2222,3333,4444], 'y':[1211,1322,1260,5555]};
df=pd.DataFrame(data=data);
ax1=df.plot('x', 'y', kind='scatter', c='lightblue', s=50, edgecolors='black')
#Create dummy variables x and y in a dataframe and plot in a scatter plot with the xticklabels rotated 35 degrees
data={'x':[1111,2222,3333,4444], 'y':[1211,1322,1260,5555]};
df=pd.DataFrame(data=data);
ax1=df.plot('x', 'y', kind='scatter', c='lightblue', s=50, edgecolors='black')
This generates a generic plot with labeled x- and y- axes and x- and y- ticklabels.
(generic x-y scatter plot with default axis and tickmark labels)
Now, if I want to rotate the xticklabels and horizontally align them to the right, that is where I run into the disappearing xticklabels:
#I would like to change the angle of rotation of the xticklabels of the ax1 handle.
labels=ax1.get_xticklabels()
print(labels)
ax1.set_xticklabels(labels, rotation=40)
ax1.set_xticklabels(labels, ha="right")
Now the xticklabels have disappeared. I've added a line to print the xticklabels because most examples perform the set_xticklabels when custom labels are being affixed to the plot. I just want to use what was already plotted. I think that the problem may lie in the contents of the 'labels' variable that I populated with get_xticklabels, but I am having trouble connecting the dots here. Any help understanding this will be greatly appreciated!
If you don't need pandas, you could just do this.
import matplotlib.pyplot as plt
data = {'x': [1111, 2222, 3333, 4444], 'y': [1211, 1322, 1260, 5555]};
fig, ax = plt.subplots()
ax.scatter(data['x'], data['y'], ec='k', fc='lightblue', s=50)
plt.xticks(rotation=45, ha='right')
plt.show()
I have created a chart based on three values in my 'result' field. Do you know how I can change the colors based on the three values (Abandoned, Connected, To voice mail) using the code I already have below:
data.direction.describe()
import seaborn as sns
%matplotlib inline
import matplotlib.pyplot as plt
sns.set() # use Seaborn styles
df = data.pivot_table('call_id', index='timeslot', columns='result', aggfunc='count')
ax = df.plot(kind='bar', width=0.7, align='center', stacked=False, rot=90, figsize=(12,6), legend=False, zorder=3)
plt.grid(zorder=0)
plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.3))
plt.xlabel("Timeslot")
plt.ylabel("Number of calls")
plt.title("Figure 4: Number of calls connected to the admin line by time slot")
ax.spines['bottom'].set_color('black')
ax.spines['top'].set_color('white')
ax.spines['right'].set_color('white')
ax.spines['left'].set_color('black')
ax.yaxis.label.set_color('black')
ax.xaxis.label.set_color('black')
ax.title.set_color('black')
ax.patch.set_facecolor('white')
plt.savefig('figure4.png', dpi=300, facecolor=ax.get_facecolor(), transparent=True, bbox_inches='tight', pad_inches=0.1)
plt.show()
This is how it currently looks but I want to be able to choose the colors. Chart
Since you are using pandas, I'd suggest that you add your colors to the call to df.plot by using the color parameter.
ax = df.plot(color=my_colors, kind='bar', width=0.7,
Where 'my_colors' is a list of the colors you want to use.
This question already has an answer here:
seaborn is not plotting within defined subplots
(1 answer)
Closed 1 year ago.
The seaborn documentation makes a distinction between figure-level and axes-level functions: https://seaborn.pydata.org/introduction.html#figure-level-and-axes-level-functions
I understand that functions like sns.boxplot can take an axis as argument, and can therefore be used within subplots.
But how about sns.relplot() ? Is there no way to put that into subplots?
More generally, is there any way to get seaborn to generate line plots within subplots?
For example, this doesn't work:
fig,ax=plt.subplots(2)
sns.relplot(x,y, ax=ax[0])
because relplot doesn't take axes as an argument.
Well that's not true. You can indeed pass axis objects to relplot. Below is a minimal answer. The key point here is to close the empty axis objects returned by relplot. You can then also use ax[0] or ax[1] to add additional curves to your individual subfigures just like you would do with matplotlib.
import seaborn as sns
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2)
xdata = np.arange(50)
sns.set(style="ticks")
tips = sns.load_dataset("tips")
g1 = sns.relplot(x="total_bill", y="tip", hue="day", data=tips, ax=ax[0])
g2 = sns.relplot(x="total_bill", y="tip", hue="day", data=tips, ax=ax[1])
# Now you can add any curves to individual axis objects
ax[0].plot(xdata, xdata/5)
# You will have to close the additional empty figures returned by replot
plt.close(g1.fig)
plt.close(g2.fig)
plt.tight_layout()
You can also make line plot solely using seaborn as
import seaborn as sns
import numpy as np
x = np.linspace(0, 5, 100)
y = x**2
ax = sns.lineplot(x, y)
ax.set_xlabel('x-label')
ax.set_ylabel('y-label')