In this lesson, we try to use matplotlib to draw some more advanced statistical charts. As said before, you can learn how to use matplotlib and how to draw more advanced charts through the documentation and examples provided by the official matplotlib website. Especially when customizing some more complex charts, we recommend that you directly find an example from the official site and then only make corresponding changes. This "copy + modify" way can greatly improve work efficiency, because most of the time your code is only different in the data, and there is no need to do repetitive and boring work.
A bubble chart can be used to understand the relationship among three variables. By comparing the position and size of bubbles, we can analyze the relationships among data dimensions. For example, in the scatter plot we drew earlier for monthly income and online-shopping expense, we had already found a positive correlation between the two. If we add a third variable, shopping frequency, then we need a bubble chart.
income = np.array([5550, 7500, 10500, 15000, 20000, 25000, 30000, 40000])
outcome = np.array([800, 1800, 1250, 2000, 1800, 2100, 2500, 3500])
nums = np.array([5, 3, 10, 5, 12, 20, 8, 10])
plt.scatter(income, outcome, s=nums * 30, c=nums, cmap='Reds')
plt.colorbar()
plt.show()Output:
An area chart is also called a stacked line chart. It is based on a line chart, but the area under the line is filled with color. It is used to show values across continuous intervals or time spans, and is generally used to show trends and compare values. The example below uses an area chart to show the time spent on sleeping, eating, working, and playing from Monday to Sunday.
plt.figure(figsize=(8, 4))
days = np.arange(7)
sleeping = [7, 8, 6, 6, 7, 8, 10]
eating = [2, 3, 2, 1, 2, 3, 2]
working = [7, 8, 7, 8, 6, 2, 3]
playing = [8, 5, 9, 9, 9, 11, 9]
plt.stackplot(days, sleeping, eating, working, playing)
plt.xticks(days, labels=[f'Weekday {x}' for x in ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']])
plt.legend(['Sleeping', 'Eating', 'Working', 'Playing'], fontsize=10)
plt.show()Output:
Radar charts are usually used to compare multiple quantitative indicators, and are good for seeing which variables have similar values, or which values are low and which are high. Readers who often watch basketball or football broadcasts should be familiar with radar charts. The essence of a radar chart is still a line chart, but it is mapped to polar coordinates. When drawing a radar chart, we need to make the line closed, which means connecting the end back to the beginning.
labels = np.array(['Speed', 'Strength', 'Experience', 'Defense', 'Serve', 'Technique'])
malong_values = np.array([93, 95, 98, 92, 96, 97])
shuigu_values = np.array([30, 40, 65, 80, 45, 60])
angles = np.linspace(0, 2 * np.pi, labels.size, endpoint=False)
malong_values = np.append(malong_values, malong_values[0])
shuigu_values = np.append(shuigu_values, shuigu_values[0])
angles = np.append(angles, angles[0])
plt.figure(figsize=(4, 4), dpi=120)
ax = plt.subplot(projection='polar')
plt.plot(angles, malong_values, color='r', linewidth=2, label='Ma Long')
plt.fill(angles, malong_values, color='r', alpha=0.3)
plt.plot(angles, shuigu_values, color='g', linewidth=2, label='Jun Mizutani')
plt.fill(angles, shuigu_values, color='g', alpha=0.2)
ax.legend()
plt.show()Output:
A rose chart is a bar chart mapped to polar coordinates. It was invented by Florence Nightingale and was used to present seasonal mortality in military hospitals. Because the relation between radius and area is quadratic, the Nightingale rose chart magnifies proportional differences, especially for values that are close to each other. At the same time, because the circle has a periodic nature, the Nightingale rose chart is also suitable for representing time concepts in a cycle, such as weekdays or months.
group1 = np.random.randint(20, 50, 4)
group2 = np.random.randint(10, 60, 4)
x = np.array([f'Group A-Q{i}' for i in range(1, 5)] + [f'Group B-Q{i}' for i in range(1, 5)])
y = np.array(group1.tolist() + group2.tolist())
theta = np.linspace(0, 2 * np.pi, x.size, endpoint=False)
width = 2 * np.pi / x.size
colors = np.random.rand(8, 3)
ax = plt.subplot(projection='polar')
plt.bar(theta, y, width=width, color=colors, bottom=0)
ax.set_thetagrids(theta * 180 / np.pi, x, fontsize=10)
plt.show()Output:
Matplotlib can also be used to draw 3D charts. You can check the official documentation for more details. Here we use a simple piece of code to show how to draw a 3D chart.
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(8, 4), dpi=120)
ax = Axes3D(fig, auto_add_to_figure=False)
fig.add_axes(ax)
x = np.arange(-2, 2, 0.1)
y = np.arange(-2, 2, 0.1)
x, y = np.meshgrid(x, y)
z = (1 - y ** 5 + x ** 5) * np.exp(-x ** 2 - y ** 2)
ax.plot_surface(x, y, z)
plt.show()Output:
It should be pointed out that the 3D chart rendered in JupyterLab is not a real interactive 3D chart, because you cannot change the viewing angle, rotate it, or zoom it freely. If you want to see the real 3D effect, you need to render the chart into a Qt window. For that, we can first install the third-party library PyQt6.
%pip install PyQt6Then we use a magic command to let JupyterLab render the chart into a Qt window.
%matplotlib qtAfter doing that, we can rerun the 3D plotting code. In the Qt window, we can rotate and zoom the 3D chart with the mouse, and we can also inspect part of the data in the chart. It is quite nice.





