1

I am trying to reproduce the table of barplots (created below in tableau) in Python.

The Plot that I am trying to recreate 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()

An example plot from Pandas for ONE MODEL

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"]

1 Answer 1

4

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)

enter image description here

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)

enter image description here

Refer to the documentation of FacetGrid and the numerous posts here on SO on how to tweak the aspect of the plot even further.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.