matplotlib学习笔记

阅读量: searchstar 2023-10-18 19:28:00
Categories: Tags:

pyplot

import matplotlib.pyplot as plt

yscale: https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.yscale.html

非阻塞显示图片:plt.show(block=False)

开始画下一张:plt.figure()

散点图 plt.scatter

交互式散点图:https://mpld3.github.io/examples/scatter_tooltip.html

legend

要用Line2D画: https://stackoverflow.com/questions/47391702/how-to-make-a-colored-markers-legend-from-scratch

调整宽度用legend的参数handlelength:

https://stackoverflow.com/questions/66809947/matplotlib-change-length-of-legend-lines

https://stackoverflow.com/questions/20048352/how-to-adjust-the-size-of-matplotlib-legend-box

折线图 plt.plot

plt.plot(y)的横坐标是从0开始的数组下标。

legend

Whether the legend should be drawn on a patch (frame).

tight_layout

Padding (height/width) between edges of adjacent subplots, as a fraction of the font size.

Axes

ax = plt.gca()

文档:https://matplotlib.org/stable/api/axes_api.html

来源:https://stackoverflow.com/questions/15067668/how-to-get-a-matplotlib-axes-instance

tick_params

ax.tick_params(axis='y', which='major', labelsize=8)

set_title

Positional, required: label

Optional: fontdict

set_xticks

Positional, required: ticks

Optional: labels (list-like)

set_xlabel

plt.xlabel一样。

Positional, required: xlabel

Optional: labelpad, fontsize

比方说如果xlabel超过了右边界,可以设置loc='right'来让它与右边界对齐,就不会超过右边界了。

set_xlim, set_ylim

设置Y轴最小值:

ax.set_ylim(bottom=0)

来源:https://stackoverflow.com/a/22642641/13688160

set_yscale

ax.set_yscale('log')

annotate 画箭头

The point (x, y) to annotate. The coordinate system is determined by xycoords.

The position (x, y) to place the text at. The coordinate system is determined by textcoords.

完整列表见文档。这里放常用的。

Value Description
data Use the coordinate system of the object being annotated (default)
figure fraction Fraction of figure from lower left
subfigure fraction Fraction of subfigure from lower left
axes fraction Fraction of axes from lower left

其他参数传给了Text。常用的:

常用值:bold

参考:https://stackoverflow.com/questions/36162414/how-to-add-bold-annotated-text-to-a-plot

ticklabel_format

比如把tick设置成

ax.ticklabel_format(style='sci', scilimits=(4, 4), useMathText=True)

tick formatter

文档:https://matplotlib.org/stable/gallery/ticks/tick-formatters.html

例子:

ax1.xaxis.set_major_formatter(lambda x, pos: str(x-5))

set_label_coords

例子:

ax.xaxis.set_label_coords(0.1, -0.19)

grid

官方文档:https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.grid.html

让参考线在柱状图的柱子后面:

# https://stackoverflow.com/a/68344604
ax.set_axisbelow(True)

给y轴画参考线:

ax.grid(axis='y')

指定指数

比如指定指数为1e-9:

from matplotlib.ticker import ScalarFormatter
y_formatter = ScalarFormatter()
y_formatter.set_powerlimits((-9, -9))
ax.yaxis.set_major_formatter(y_formatter)

官方文档:https://matplotlib.org/stable/api/ticker_api.html#matplotlib.ticker.ScalarFormatter.set_powerlimits

来源:https://stackoverflow.com/a/77442842/13688160

设置fontsize:

ax.yaxis.get_offset_text().set_fontsize(8)

来源:https://stackoverflow.com/a/34228384/13688160

colorbar

https://matplotlib.org/stable/users/explain/colors/colormapnorms.html

例子:

import numpy as np
import matplotlib.pyplot as plt 
from matplotlib import cm, colors

ax = plt.gca()
cmap = plt.get_cmap('coolwarm')

# need to normalize because color maps are defined in [0, 1]
norm = colors.TwoSlopeNorm(1, vmin=0, vmax=5)

norm_cmap = cm.ScalarMappable(norm=norm, cmap=cmap)

for i in np.linspace(0, 5, 100):
    plt.scatter(i, i, color=norm_cmap.to_rgba(i))
cb = plt.colorbar(norm_cmap, ax=ax, ticks=[0, 0.5, 1, 2, 3, 4, 5])
cb.ax.tick_params(labelsize=8)
plt.show()

参考:

https://stackoverflow.com/questions/73510185/how-to-add-colorbar-in-matplotlib

https://stackoverflow.com/questions/29074820/how-do-i-change-the-font-size-of-ticks-of-matplotlib-pyplot-colorbar-colorbarbas

翻转坐标轴

https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.invert_yaxis.html

子图

用gridspec

官方文档:https://matplotlib.org/stable/api/_as_gen/matplotlib.gridspec.GridSpec.html

官方例子:https://matplotlib.org/stable/gallery/subplots_axes_and_figures/align_labels_demo.html#sphx-glr-gallery-subplots-axes-and-figures-align-labels-demo-py

常用:

figure = plt.figure(dpi = 300, figsize = (xx, xx), constrained_layout=True)
gs = gridspec.GridSpec(1, 3, figure=figure)

其中constrained_layouttight_layout更好。

plt.figure参数:https://matplotlib.org/stable/api/figure_api.html#matplotlib.figure.Figure

调整坐标轴label与tick label之间的空隙

labelpad

官方文档:https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.xlabel.html

设置tick的个数

比如让y轴有4个tick:

plt.locator_params(axis='y', nbins=4)

来源:https://stackoverflow.com/a/13418954/13688160

很坑的是,log scale用这种方式无效,需要手动设置ticks:

plt.yscale('log')
# 设置成log scale似乎会清空ticks,所以要把设置ticks放后面
plt.yticks([1e5, 1e6, 1e7], fontsize=8)
# plt.yticks似乎会消除minor ticks,所以还得把它们补上
# 其中numticks比较玄学,似乎大于3就行。这里直接设置成一个大数,就肯定不会有问题了。
ax.yaxis.set_minor_locator(LogLocator(base=10, subs=np.arange(2, 10) * 0.1, numticks=233))

疑难杂症

Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.

sudo apt install python3-tk

来源:https://stackoverflow.com/questions/56656777/userwarning-matplotlib-is-currently-using-agg-which-is-a-non-gui-backend-so

在安装了ttf-mscorefonts-installer的情况下matplotlib找不到Times New Roman

sudo apt install msttcorefonts -qq
rm ~/.cache/matplotlib -rf

参考:https://stackoverflow.com/questions/42097053/matplotlib-cannot-find-basic-fonts

已知的问题

plt.legend顺序似乎只能是按列的,要改成按行只能手动reorder: https://stackoverflow.com/questions/29639973/custom-legend-in-pandas-bar-plot-matplotlib