I have been trying to work on plotting a nice violin plot to present my data using Matplotlib library in Python. This is the code I have used:
ax.violinplot(vdistances,showmeans=False,showmedians=True)
ax.set_title('Distance analysis for molecule 1')
ax.set_xlabel('Atomic distances')
ax.set_ylabel('Distances in Amstrongs')
ax.set_xticks([x for x in range(1,len(distances) 1)])
plt.show()
And this is what I have come up with:
What I have been wondering is if it is possible to assign different tones of the same color to each of the violins depending on how broad the distribution is, and so the more disperse the data is.
CodePudding user response:
You could loop through the generated violins, extract their height and use that to set a color:
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator
from matplotlib.cm import ScalarMappable
import numpy as np
fig, ax = plt.subplots(figsize=(12, 5))
vdistances = np.random.normal(np.random.uniform(10, 20, (20, 10)), np.random.uniform(2, 5, (20, 10)))
violins = ax.violinplot(vdistances, showmeans=False, showmedians=True)
ax.xaxis.set_major_locator(MultipleLocator(1))
heights = [violin.get_paths()[0].get_extents().height for violin in violins['bodies']]
norm = plt.Normalize(min(heights), max(heights))
cmap = plt.get_cmap('plasma')
for violin, height in zip(violins['bodies'], heights):
violin.set_color(cmap(norm(height)))
violin.set_alpha(0.5)
plt.colorbar(ScalarMappable(norm=norm, cmap=cmap), alpha=violin.get_alpha(), label='Violin Extent', ax=ax)
plt.tight_layout()
plt.show()