I have the following code:
import numpy as np
import pandas as pd
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
matplotlib.style.use('ggplot')
import seaborn as sns
sns.set(style="white")
# Create a dataset with many short random walks
rs = np.random.RandomState(4)
pos = rs.randint(-1, 2, (10, 5)).cumsum(axis=1)
pos -= pos[:, 0, np.newaxis]
step = np.tile(range(5), 10)
walk = np.repeat(range(10), 5)
df = pd.DataFrame(np.c_[pos.flat, step, walk],
columns=["position", "step", "walk"])
# Initialize a grid of plots with an Axes for each walk
grid = sns.FacetGrid(df, col="walk", hue="walk", col_wrap=5, size=5,
aspect=1)
# Draw a bar plot to show the trajectory of each random walk
grid.map(sns.barplot, "step", "position", palette="Set3").add_legend();
grid.savefig("/Users/mymacmini/Desktop/test_fig.png")
#sns.plt.show()
Which makes this plot:
As you can see I get the legend wrong. How can I make it right?
To change the position of a legend in a seaborn plot, you can use the plt. legend() command. The default location is “best” – which is where Matplotlib automatically finds a location for the legend based on where it avoids covering any data points.
Set the figure size and adjust the padding between and around the subplots. Make a Pandas dataframe with three coulmns, column1, column2 and column3. Draw a scatterplot with possibility of several semantic groupings. To place the legend outside the plot, use bbox_to_anchor in legend() method.
FacetGrid object takes a dataframe as input and the names of the variables that will form the row, column, or hue dimensions of the grid. The variables should be categorical and the data at each level of the variable will be used for a facet along that axis.
If you create the FacetGrid directly, as in the original example, it automatically adds column and row labels instead of individual subplot titles. We can still add a title to the whole thing: from matplotlib. pyplot import scatter as plt_scatter g = sns.
Some how there is one legend item for each of the subplot. Looks like if we want to have legend corresponds to the bars in each of the subplot, we have to manually make them.
# Let's just make a 1-by-2 plot
df = df.head(10)
# Initialize a grid of plots with an Axes for each walk
grid = sns.FacetGrid(df, col="walk", hue="walk", col_wrap=2, size=5,
aspect=1)
# Draw a bar plot to show the trajectory of each random walk
bp = grid.map(sns.barplot, "step", "position", palette="Set3")
# The color cycles are going to all the same, doesn't matter which axes we use
Ax = bp.axes[0]
# Some how for a plot of 5 bars, there are 6 patches, what is the 6th one?
Boxes = [item for item in Ax.get_children()
if isinstance(item, matplotlib.patches.Rectangle)][:-1]
# There is no labels, need to define the labels
legend_labels = ['a', 'b', 'c', 'd', 'e']
# 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(handles=legend_patches)
When the legend doesn't work out you can always make your own easily like this:
import matplotlib
name_to_color = {
'Expected': 'green',
'Provided': 'red',
'Difference': 'blue',
}
patches = [matplotlib.patches.Patch(color=v, label=k) for k,v in name_to_color.items()]
matplotlib.pyplot.legend(handles=patches)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With