Python uses the Matplotlib library to draw dual y-axis graphics (bar chart + line chart)

Today is the first time I write a pitfall diary series. This series is used to record the problems and results encountered in the learning process of Python and R. Today we introduce some basic usage and pitfalls of using Python’s matplotlib library to draw two y-axis graphs. I hope it can help everyone, and I also hope you can give suggestions. Welcome to leave a message for communication.

Introduction to Matplotlib

Matplotlib is a commonly used visualization tool in Python data analysis. It is also the basis for other advanced drawing interfaces (such as seaborn, HoloViews, ggplot, etc.) and professional drawing tools (such as Cartopy). Matplotlib can create publication-quality graphics, make interactive graphics, customize visual style and layout, export to multiple file formats, and be embedded in JupyterLab and graphical user interfaces. For more exploration content, please check the Matplotlib official website or the Matplotlib Chinese website .

Install

pip install matplotlib

drawing elements

The following are the components of Matplotlib graphics, from the Matplotlib official website. For detailed usage, see the Quick Start Guide - Matplotlib 3.7.1 documentation .alt

When setting text label content such as title or axis name, if it contains Chinese characters and appears garbled, you need to add the following code. If it still cannot be solved, you can try changing the SimHeifont FangSongto another font.

plt.rcParams['font.sans-serif']=['SimHei'] # 用来设置字体样式以正常显示中文标签(黑体)

If the number is negative, it may also be garbled. The solution is:

plt.rcParams['axes.unicode_minus']=False

Matplotlib provides a variety of graphics, including basic bar charts, line charts, scatter plots, box plots, scatter plots, pie charts, etc. It also provides advanced visualization graphics such as polar coordinate charts and 3D graphics (if you don’t want to see For official documents, you can check out an article on Zhihu to learn the basic method of drawing the above graphics), you can modify the image details through the above parameters, and you can combine various graphics.

Dual y-axis graph

Draw a single y-axis graph

import numpy as np  
import matplotlib.pyplot as plt

# 生成一些示例数据
x = np.arange(10)
y = np.random.randint(0,20,10)

# 绘制折线图,设置颜色
plt.plot(x,y,color='blue')
# 设置x轴和y轴的标签,指明坐标含义
plt.xlabel('x轴', fontdict={ 'size': 16})
plt.ylabel('y轴', fontdict={ 'size': 16})
#设置图标题
plt.title('折线图')

# 设置中文显示
plt.rcParams['font.sans-serif']=['SimHei']
#展示图片
plt.show()

alt
#画柱状图
plt.bar(x,y,color='blue')#只要将以上代码中的`plot`改为`bar`
alt

Double y-axis line chart

import numpy as np  
import matplotlib.pyplot as plt

# 生成一些示例数据
x = np.arange(10)
y1 = np.random.randint(10, size=10)
y2 = np.random.randint(10, size=10)

# 创建一个图形和两个y轴
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
#绘制折线图
line1 = ax1.plot(x, y1,label='y1轴', color='royalblue', marker='o', ls='-.')
line2 = ax2.plot(x, y2, label='y2轴', color='tomato', marker=None, ls='--')

# 设置x轴和y轴的标签,指明坐标含义
ax1.set_xlabel('x轴', fontdict={ 'size': 16})
ax1.set_ylabel('y1轴',fontdict={ 'size': 16})
ax2.set_ylabel('y2轴',fontdict={ 'size': 16})
#添加图表题
plt.title('双y轴折线图')
#添加图例
plt.legend()
# 设置中文显示
plt.rcParams['font.sans-serif']=['SimHei']
#展示图片
plt.show()
alt

Solving the legend: There is no legend set through the above method y1轴, and no error message appears, indicating that both legends are displayed. It is very likely that y2轴the legend has y1轴covered the legend. By displaying the legends of the two axes separately, it is proved that they are indeed covered.

#将`plt.legend()`改为以下代码
ax1.legend(loc='upper right')
ax2.legend(loc='upper left')
alt

But it’s too ugly to display the two legends separately. I still hope that the legends can be combined together.

lines = line1 + line2  
labels = [h.get_label() for h in lines]
plt.legend(lines, labels, loc='upper right')
alt

Setting the axis seems a bit inconvenient. It might look better if the axis and line are the same color.

#设置轴标签颜色  
ax1.tick_params('y', colors='royalblue')
ax2.tick_params('y', colors='tomato')
#设置轴颜色
ax1.spines['left'].set_color('royalblue')
ax2.spines['left'].set_color('royalblue')
ax1.spines['right'].set_color('tomato')
ax2.spines['right'].set_color('tomato')
alt

The color change of the two y-axes does look better, but the upper axis is a bit abrupt, so remove it.

ax1.spines['top'].set_visible(False)  
ax2.spines['top'].set_visible(False)
alt

Histogram + Line Chart

Change the y2 above to a bar chart and draw a double y-axis chart of the bar chart and the line chart.

import numpy as np  
import matplotlib.pyplot as plt
# 生成一些示例数据
x = np.arange(10)
y1 = np.random.randint(10, size=10)
y2 = np.random.randint(10, size=10)
# 创建一个图形和两个y轴
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
#绘制图形
bar = ax1.bar(x, y1, label='y1轴', color='tomato', width=0.4)
line = ax2.plot(x, y2,label='y2轴', color='royalblue', marker='o', ls='-.')
# 设置x轴和y轴的标签,指明坐标含义
ax1.set_xlabel('x轴', fontdict={ 'size': 16})
ax1.set_ylabel('y1轴',fontdict={ 'size': 16})
ax2.set_ylabel('y2轴',fontdict={ 'size': 16})
#添加图表题
plt.title('双y轴折线图')
#添加图例
lines = line + bar
labels = [h.get_label() for h in lines]
plt.legend(lines, labels, loc='upper right')
#设置轴标签颜色
ax1.tick_params('y', colors='royalblue')
ax2.tick_params('y', colors='tomato')
#设置轴颜色
ax1.spines['left'].set_color('royalblue')
ax2.spines['left'].set_color('royalblue')
ax1.spines['right'].set_color('tomato')
ax2.spines['right'].set_color('tomato')
#去掉上轴线
ax1.spines['top'].set_visible(False)
ax2.spines['top'].set_visible(False)
# 设置中文显示
plt.rcParams['font.sans-serif']=['SimHei']
#展示图片
plt.show()

Hey hey, an error was reported. The return value of matplotlib's bar chart is a BarContainer tuple object, while the return value of the line chart is a Line2D list object.alt alt

Use the matplotlib.pyplot.plot() function to draw a polyline and assign its return value to a variable. Please note that the plot() function returns a list containing a Line2D object, not a Line2D object itself. Therefore, you need to add a comma after the variable, or specify the index of the list as 0 when using the get_label() method, to correctly obtain the label of the Line2D object. So #绘制图形 change the above module to

 
#绘制图形
bar = ax1.bar(x, y1, label='y1轴', color='tomato', width=0.4)
line, = ax2.plot(x, y2,label='y2轴', color='royalblue', marker='o', ls='-.')

alt

Okay, that’s it for today’s diary of pitfalls. As for other modification details of the picture, you can try it yourself. If you try more, you will always find different pitfalls.

This article is published by mdnice multi-platform

Guess you like

Origin blog.csdn.net/XIAOWANGaxs/article/details/131038484