简体   繁体   中英

Matplotlib: Can we draw a histogram and a box plot on a same chart?

I have a question about drawing a histogram and a box plot Matplotlib.

I know I can draw a histogram and a box plot individually. My question is, is it possible to draw them on the same graph, such as a chart shown in this website? Springer Images

Thank you very much!

There are several ways to achieve this with matplotlib. The plt.subplots() method, and the AxesGrid1 and gridspec toolkits all provide very elegant solutions, but might take time to learn.

A simple, brute-force way to do this would be to manually add the axes objects to a figure yourself.

import numpy as np
import matplotlib.pyplot as plt

# fake data
x = np.random.lognormal(mean=2.25, sigma=0.75, size=37)

# setup the figure and axes
fig = plt.figure(figsize=(6,4))
bpAx = fig.add_axes([0.2, 0.7, 0.7, 0.2])   # left, bottom, width, height:
                                            # (adjust as necessary)
histAx = fig.add_axes([0.2, 0.2, 0.7, 0.5]) # left specs should match and
                                            # bottom + height on this line should
                                            # equal bottom on bpAx line
# plot stuff
bp = bpAx.boxplot(x, notch=True, vert=False)
h = histAx.hist(x, bins=7)

# confirm that the axes line up 
xlims = np.array([bpAx.get_xlim(), histAx.get_xlim()])
for ax in [bpAx, histAx]:
    ax.set_xlim([xlims.min(), xlims.max()])

bpAx.set_xticklabels([])  # clear out overlapping xlabels
bpAx.set_yticks([])  # don't need that 1 tick mark
plt.show()

Yes and the best way I've seen to handle this can be found here . Copy of code and graph:

# Import library and dataset
import seaborn as sns
import matplotlib.pyplot as plt
df = sns.load_dataset('iris')
 
# Cut the window in 2 parts
f, (ax_box, ax_hist) = plt.subplots(2, sharex=True, gridspec_kw={"height_ratios": (.15, .85)})
 
# Add a graph in each part
sns.boxplot(df["sepal_length"], ax=ax_box)
sns.distplot(df["sepal_length"], ax=ax_hist)
 
# Remove x axis name for the boxplot
ax_box.set(xlabel='')

在此处输入图片说明

I was looking for something similar and this worked for me. The image link is here https://raw.githubusercontent.com/preetihemant/preetihemant.github.io/master/images/hist_boxplot.png

plt.subplot(2,1,1)
plt.hist(data,histtype='bar',bins=[values]) 
plt.xlabel('x-label')
plt.ylabel('y-label')
plt.title('Graph title')

plt.subplot(2,1,2)
plt.boxplot(values)

plt.show()

There is a general solution as a free library of seventeen matplotlib graphics utilities + user guide here: https://www.mlbridgeresearch.com/products/free-article-2 . I got tired of interrupting my research to write utility software, so I've accumulated libraries that address common needs. The code is well-documented and it works well. Here is an example.

from sklearn.datasets import load_iris

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

from statistics_utilities import histogram
from statistics_utilities import box_plot_basic

data = load_iris()
# iris, using the label column as a categorical
df = pd.DataFrame(data.data, columns=data.feature_names)
df['label'] = data.target

print(data.feature_names)

# setup the plot grid
plt.style.use('seaborn-darkgrid')
fig, ax = plt.subplots(1, 2)
ax = np.reshape(ax, (1, 2))

variable_name = 'sepal length (cm)'

# Place the histogram on the grid - pass the Axes.
# Plots a single histogram for a quantitative variable using seaborn's distplot().
# See also histogram_grid(), which plots a grid of histograms for a list of
# quantitative variables
hist_type = 'frequency'
# displays summary statistics in a custom legend, set legend=False to turn off.
ax[0, 0] = histogram(df, variable_name=variable_name, bins=20, kde=False, statistics='all',
                     hist_type=hist_type, title=None, ax=ax[0, 0])

# Place the box plot on the grid - pass the Axes
# Plots a single box_plot for a quantitative variable using matplotlib's boxplot().
# See also box_plot() and box_plot_groupby, which plots a quantitative variable
# by one or two categorical variables.
box_orientation = 'vertical'
box_width = .2
ax[0, 1] = box_plot_basic(df, variable_name=variable_name,
                          box_orientation=box_orientation, box_width=box_width, title=None,
                          ax=ax[0, 1])

# adjustments to plot size and spacing
fig.set_size_inches(13, 6)
fig.subplots_adjust(wspace=.55, left=0.035, right=.985, top=.925, bottom=.1)
fig.suptitle('iris dataset', fontsize=13)

plt.show()
plt.close()

历史+盒子

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM