Is there a default function/method in seaborn to rename the xticks of a boxplot without the need of changing the input data frame?
I haven't seen anything in documentation neither googling this
Since there is no code or data, customizing the x-axis label based on the example from the official reference can be done by setting any string. As an addition, ticks can also be achieved by converting an existing string or setting a list with the same number of ticks.
import seaborn as sns
import matplotlib.pyplot as plt
sns.set_theme(style="whitegrid")
tips = sns.load_dataset("tips")
ax = sns.boxplot(x="day", y="total_bill", data=tips)
xlabel = ax.get_xlabel()
print(xlabel)
labels = ax.get_xticklabels()
print(labels)
labels = [x.get_text().upper()for x in labels]
ax.set_xticklabels(labels)
ax.set_xlabel('dayofweek')
plt.show()
Graph before customization
This replace the name of the box
ax.set_xticklabels(["First box","Second box"])
Related
I have a box plot that I create using the following command:
sns.boxplot(y='points_per_block', x='block', data=data, hue='habit_trial')
So the different colors represent whether the trial was a habit trial or not (0,1). I want to also plot the individual data points, which I tried to achieve using:
sns.stripplot(y='points_per_block', x='block', data=data, hue='habit_trial')
The result was the following
I want the individual points to display over the corresponding box plots. Is there a way to do this without resorting to hacking their positions in some manner? The problem comes from the fact that the separation of data using hue works differently for stripplot and boxplot but I would have thought that these would be easily combinable.
Thanks in advance.
Seaborn functions working with categorical data usually have a dodge= parameter indicating whether data with different hue should be separated a bit. For a boxplot, dodge defaults to True, as it usually would look bad without dodging. For a stripplot defaults to dodge=False.
The following example also shows how the legend can be updated (matplotlib 3.4 is needed for HandlerTuple):
import seaborn as sns
from matplotlib.legend_handler import HandlerTuple
tips = sns.load_dataset("tips")
ax = sns.boxplot(data=tips, x="day", y="total_bill",
hue="smoker", hue_order=['Yes', 'No'], boxprops={'alpha': 0.4})
sns.stripplot(data=tips, x="day", y="total_bill",
hue="smoker", hue_order=['Yes', 'No'], dodge=True, ax=ax)
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=[(handles[0], handles[2]), (handles[1], handles[3])],
labels=['Smoker', 'Non-smoker'],
loc='upper left', handlelength=4,
handler_map={tuple: HandlerTuple(ndivide=None)})
I am trying to make a line plot using seaborn and in the image link I have attached
it seems like it did not show the required dates (daily) in the x-axis. How can I fix this chart?
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.style.use(['ggplot'])
import seaborn as sns
sns.set_style("whitegrid")
fig, g = plt.subplots(figsize = (20,6))
g = sns.lineplot(x="photosim_date", y="tdpower_mean", hue="tool_id", style="tool_id", data=df1, dashes=False, ax=g)
plt.ylim(80,140)
plt.title("L8 PhotoSIM SDET TDP Data")
plt.show(g)
You can change the x-axis tick locator.
loc = matplotlib.dates.DayLocator(bymonthday=range(1,32))
ax.xaxis.set_major_locator(loc)
Be wary that the axis labels will most likely overlap in this case. You can use fig.autofmt_xdate() to automatically rotate the labels.
My dataframe contains two columns, I would like to plot their values in a barplot. Like this:
import seaborn as sns
# load sample data and drop all but two columns
tips = sns.load_dataset("tips")
tips= tips[["day", "total_bill"]]
sns.set(style="whitegrid")
ax = sns.barplot(x="day", y="total_bill", data=tips)
On top of this barplot, I would also like to add a legend with labels for each x value. Seaborn supports this, but as far as I can see, it works only when you specify a hue argument. Each label in the legend then corresponds to a hue value.
Can I create a legend with explanations for the x values?
This might be a confusing question. I don't want to rename the label for the axis or the ticks along the axis. Instead, I would like to have a separate legend with additional explanations. My bars give me some nice space to put this legend and the explanations would be too long to have them as ticks.
Is this what you want:
sns.set(style="whitegrid")
ax = sns.barplot(x="day", y="total_bill", data=tips)
ax.legend(ax.patches, ['1','2','3','Something that I can\'t say'], loc=[1.01,0.5])
Output:
I'm using the function regplot in seaborn to plot a figure. Is there a way to adjust the size of the dots? I didn't think I can find it.
link
Use the scatter_kws= argument. You can pass a dictionary of options to be passed to plt.scatter
import seaborn as sns
tips = sns.load_dataset("tips")
ax = sns.regplot(x="total_bill", y="tip", data=tips, scatter_kws={'s':100, 'facecolor':'red'})
I have a pandas DataFrame df which I visualize with subplots of a seaborn.barplot. My problem is that I want to move my legend inside one of the subplots.
To create subplots based on a condition (in my case Area), I use seaborn.FacetGrid. This is the code I use:
import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns
# .. load data
grid = sns.FacetGrid(df, col="Area", col_order=['F1','F2','F3'])
bp = grid.map(sns.barplot,'Param','Time','Method')
bp.add_legend()
bp.set_titles("{col_name}")
bp.set_ylabels("Time (s)")
bp.set_xlabels("Number")
sns.plt.show()
Which generates this plot:
You see that the legend here is totally at the right, but I would like to have it inside one of the plots (for example the left one) since my original data labels are quite long and the legend occupies too much space. This is the example for only 1 plot where the legend is inside the plot:
and the code:
mask = df['Area']=='F3'
ax=sns.barplot(x='Param',y='Time',hue='Method',data=df[mask])
sns.plt.show()
Test 1:
I tried the example of an answer where they have the legend in one of the subplots:
grid = sns.FacetGrid(df, col="Area", col_order=['F1','F2','F3'])
bp = grid.map(sns.barplot,'Param','Time','Method')
Ax = bp.axes[0]
Boxes = [item for item in Ax.get_children()
if isinstance(item, matplotlib.patches.Rectangle)][:-1]
legend_labels = ['So1', 'So2', 'So3', 'So4', 'So5']
# Create the legend patches
legend_patches = [matplotlib.patches.Patch(color=C, label=L) for
C, L in zip([item.get_facecolor() for item in Boxes],
legend_labels)]
# Plot the legend
plt.legend(legend_patches)
sns.plt.show()
Note that I changed plt.legend(handles=legend_patches) did not work for me therefore I use plt.legend(legend_patches) as commented in this answer. The result however is:
As you see the legend is in the third subplot and neither the colors nor labels match.
Test 2:
Finally I tried to create a subplot with a column wrap of 2 (col_wrap=2) with the idea of having the legend in the right-bottom square:
grid = sns.FacetGrid(df, col="MapPubName", col_order=['F1','F2','F3'],col_wrap=2)
but this also results in the legend being at the right:
Question: How can I get the legend inside the first subplot? Or how can I move the legend to anywhere in the grid?
You can set the legend on the specific axes you want, by using grid.axes[i][j].legend()
For your case of a 1 row, 3 column grid, you want to set grid.axes[0][0].legend() to plot on the left hand side.
Here's a simple example derived from your code, but changed to account for the sample dataset.
import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns
df = sns.load_dataset("tips")
grid = sns.FacetGrid(df, col="day")
bp = grid.map(sns.barplot,"time",'total_bill','sex')
grid.axes[0][0].legend()
bp.set_titles("{col_name}")
bp.set_ylabels("Time (s)")
bp.set_xlabels("Number")
sns.plt.show()
Use the legend_out=False option.
If you are making a faceted bar plot, you should use factorplot with kind=bar. Otherwise, if you don't explicitly specify the order for each facet, it is possible that your plot will end up being wrong.
import seaborn as sns
tips = sns.load_dataset("tips")
sns.factorplot(x="sex", y="total_bill", hue="smoker", col="day",
data=tips, kind="bar", aspect=.7, legend_out=False)