Lizardinablizzard
Lizardinablizzard

Reputation: 55

Changing from a subplot, violin plot stops working?

I want to make a plot like the first subfigure here:

import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(9, 4))

# generate some random test data
all_data = [np.random.normal(0, std, 100) for std in range(6, 10)]

# plot violin plot
axes[0].violinplot(all_data,
                   showmeans=False,
                   showmedians=True)
axes[0].set_title('violin plot')

This code works but I just want the first subplot as a separate plot, so I change to plt.figure and remove the parts related to axes[1], but I can't get the violin plot to work anymore! I have also tried a separate plot using sns.violinplot but it rotates the violin and plots them all on top of each other. Tips?

Upvotes: 0

Views: 394

Answers (2)

luuk
luuk

Reputation: 1855

If you create a figure using fig = plt.figure(), you still need to create a subplot in this figure using add_subplot(). You can do this as follows:

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(figsize=(9, 4))
axes = fig.add_subplot()

# generate some random test data
all_data = [np.random.normal(0, std, 100) for std in range(6, 10)]

# plot violin plot
axes.violinplot(all_data,
                   showmeans=False,
                   showmedians=True)
axes.set_title('violin plot')

This produces the following figure:

violin plot in a single subplot

Note that fig, axes = plt.subplots() is simply shorthand for the two lines above, and the default values for ncols and nrows are 1, so you can simply remove these arguments from your original code and it will also work:

import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(figsize=(9, 4))

# generate some random test data
all_data = [np.random.normal(0, std, 100) for std in range(6, 10)]

# plot violin plot
axes.violinplot(all_data,
                   showmeans=False,
                   showmedians=True)
axes.set_title('violin plot')

Upvotes: 1

Arne
Arne

Reputation: 10545

For simple single plots it's often easier to use matplotlib's pyplot interface rather than the object-oriented interface. Some functions have different names between these interfaces, e.g. plt.title() corresponds to ax.set_title().

import matplotlib.pyplot as plt
import numpy as np

# generate some random test data
all_data = [np.random.normal(0, std, 100) for std in range(6, 10)]

# plot violin plot
plt.violinplot(all_data,
               showmeans=False,
               showmedians=True)
plt.title('violin plot')

Upvotes: 1

Related Questions