Plotting the same chart with Matplotlib and ggplot2
By: Thiago Carvalho
Tags: Data Visualization, Ggplot2, Python, Matplotlib, R

Legends and Colors

Let’s draw the legends for our Matplotlib chart and choose a different color for the markers.

There are many ways to achieve that. One would be to draw two scatter plots that would automatically create the handles for our legend.

# PYTHON

# create a df with only legendaries

legendary = df[df['Legendary']]

# create a df with no legendaries

non = df[~df['Legendary']] # plot non legendary

plt.scatter(non.Attack, non.Defense, color='#F85C54')

# plot legendary

plt.scatter(legendary.Attack, legendary.Defense, color='#2ACC74') # plot legend

plt.legend(['no', 'yes'], title='Legendary')

Scatter Plot with Colors — Image by the author, made with Python

Since it has complete integration with Pandas, we could even plot directly from the data frame like:

legendary.plot(kind=’scatter’, x=’Attack’, y=’Defense’, color=’#2ACC74')

But we’ll use yet another way.

We’ll create a column for the colors, draw a single scatter plot, and define the legend's elements.

# PYTHON

from matplotlib.lines import Line2D # create a column with the colors

df['leg_color'] = ['#2ACC74' if i else '#F85C54' for i in df['Legendary']] # plot

plt.scatter(df.Attack, df.Defense, color=df.leg_color) # create legend elements

legend_elements = [Line2D([0], [0], marker='o', color='w',

markerfacecolor='#2ACC74', markersize=10),

Line2D([0], [0], marker='o', color='w',

markerfacecolor='#F85C54', markersize=10)]

# plot legend

plt.legend(legend_elements, ['Yes', 'No'], title='Legendary')

Scatter Plot with Colors — Image by the author, made with Python

Now let’s try moving the legend in both graphs to the bottom of the plot, and display the keys in a single row.

Starting with ggplot, we can use scale_color_manual to pass the markers' colors, labels, and a guide to the legend, which is used to set things like the title, the number of rows, and the order of the keys.

We can then use ‘theme’ to define the position of our legend and other elements of its frame.

# R

ggplot(data = poke) +

geom_point(mapping = aes(x=Attack, y=Defense, color=Legendary))+

scale_color_manual(values = c('#F85C54','#2ACC74'),

labels = c('No', 'Yes'),

guide=guide_legend(title = 'Legendary',

nrow=1,

reverse=TRUE))+

theme(legend.position = 'bottom',

legend.background = element_blank(),

legend.key = element_rect(color = NA, fill = NA))

Scatter Plot with Bottom Legend — Image by the author, made with R

In Matplotlib, we are already using a method for plotting the legend. We’ll set most of the parameters in it, like the title, number of columns, location, and frame. We won’t need to re-order the keys since we created them manually, and they’re already in the right order.

Let’s also fix the size of our plot. R-Studio allows us to define the chart's size when exporting an image, but in Matplotlib, we need to determine our plot's size with a ‘Figure.’

# PYTHON

# figure

fig, ax = plt.subplots(1, figsize=(16,8)) # plot

plt.scatter(df.Attack, df.Defense, color=df.leg_color) # create legend elements

legend_elements = [Line2D([0], [0], marker='o', color='w',

markerfacecolor='#F85C54', markersize=10),

Line2D([0], [0], marker='o', color='w',

markerfacecolor='#2ACC74', markersize=10)] # plot legend

legend = plt.legend(legend_elements, ['No', 'Yes'],

title='Legendary', ncol=2, loc='lower left',

bbox_to_anchor=(0.45, -0.15), frameon=False, fontsize=12) # adjust legend title

plt.setp(legend.get_title(),fontsize=14)

legend.get_title().set_position((-110, -18)) plt.show()

Scatter Plot with Bottom Legend — Image by the author, made with Python

Matplotlib adds the legend to the inside of the plotting area, which often gets in the way of the data, so we need to use bbox_to_anchor to move it outside and kind of guess the coordinates.

The same goes for the title position, where ggplot automatically moves the title to the side when you move it to the top or bottom. In Matplotlib, we have to set its coordinates manually.