Reputation: 1373
I am trying to reproduce the table of barplots (created below in tableau) in Python.
I am struggling to figure out how to do it python (matplotlib, seaborn, pandas).
Here is some example data that illustrates the problem:
import pandas as pd
import numpy as np
data = dict(
correlation=np.random.normal(0, 0.5, 100),
pvalue=np.random.normal(0.05, 0.02, 100),
variable=np.tile(np.array([f"variable{i}" for i in range(10)]), 10),
model=np.repeat(np.array([f"model{i}" for i in range(10)]), 10)
)
data = pd.DataFrame(data)
data["significant"] = data["pvalue"] < 0.05
data["positive"] = data["correlation"] > 0
My attempted plot for ONE MODEL ("model1"
) illustrates roughly what I am looking for. As I said I am trying to reproduce the table of barplots (shown above), which would display the results for all of the models.
example_plot_data = data.loc[data.model == "model1"]
example_plot_data.plot(
kind="bar", x="variable", y="correlation",
color=example_plot_data.positive.map({True: "b", False: "r"}),
rot=70,
)
plt.show()
Ideally these are the aesthetics I am looking for
# Aesthetics for the plots:
columns = data["model"]
rows = data["variable"]
bar_size = data["correlation"] # ideally centred on zero
bar_color = data["correlation"] # ideally centred on zero (RdBu)
bar_significance = data["significant"]
Upvotes: 1
Views: 531
Reputation: 40737
In essence, what you are trying to do can be easily done using seaborn's catplot
:
sns.catplot(data=data, x='correlation', y='variable', col='model', kind='bar', height=4, aspect=0.3)
If you want to match the aesthetics from your example, you can improve on catplot
by using FacetGrid
directly, and using a custom function for drawing the bar plot according to the colormap that you want:
from matplotlib.colors import TwoSlopeNorm
from matplotlib.cm import ScalarMappable
norm = TwoSlopeNorm(vcenter=0, vmin=-1, vmax=1)
cmap = plt.get_cmap('bwr')
def my_bar_plot(x, y, **kwargs):
plt.barh(y=y, width=np.abs(x), color=cmap(norm(x)))
g = sns.FacetGrid(data=data, col='model', height=5, aspect=0.2, sharex=True, sharey=True)
g.map(my_bar_plot, 'correlation', 'variable')
g.set_titles(col_template="{col_name}")
g.fig.colorbar(ScalarMappable(norm=norm, cmap=cmap), orientation='horizontal', ax=g.axes, fraction=0.05)
Refer to the documentation of FacetGrid
and the numerous posts here on SO on how to tweak the aspect of the plot even further.
Upvotes: 4