10 Advanced Tips for Mastering Matplotlib

Matplotlib is a popular data visualization library in Python that can generate charts with just a few lines of code. But the default approach produces simple charts. If you want to enhance the impact and clarity of your data presentation, try out the 10 advanced tips summarized in this article that can take your visualization to the next level:

1、rcParams

rcParams dictionary. It contains all Matplotlib settings for default styles used to create figures. You can import it directly from the matplotlib namespace:

 from matplotlib import rcParams
 >>> rcParams
 ...
 'axes.grid': False,
 'axes.grid.axis': 'both',
 'axes.grid.which': 'major',
 'axes.labelcolor': 'black',
 'axes.labelpad': 4.0,
 'axes.labelsize': 'medium',
 'axes.labelweight': 'normal',
 'axes.linewidth': 0.8,
 ...
 
 rcParams['figure.figsize'] = 8, 6
 rcParams['legend.fontsize'] = "large"
 rcParams['xtick.major.size'] = 4
 rcParams['xtick.minor.size'] = 1

At this time, all Matplotlib settings, if you want to modify any Matplotlib parameters, you can directly modify this dictionary, you can even serialize it locally, and then load it directly in other projects, so that each of your Matplotlib instances use are all the same configuration.

You can also call PyPlot's rcdefaults function, which will reset all parameters to their default values.

 plt.rcdefaults()

2、get_* functions

Under the hood, Matplotlib is completely object-oriented.

Each individual component seen in the diagram above is implemented as a separate class. They all inherit from the base class Matplotlib Artist.

But there are too many classes, and the parameters of each class are different, which will bring great inconvenience to use, so Matplotlib has customized many functions starting with the prefix get_, which can directly create components in the graph. Below is an example:

 fig, ax = plt.subplots()
 
 >>> [func for func in dir(ax) if func.startswith("get")]
 
 ['get_adjustable',
  'get_label',
  'get_legend',
  'get_legend_handles_labels',
  'get_lines',
  'get_navigate',
  'get_title',
  'get_transform',
  'get_xmajorticklabels',
  'get_xminorticklabels',
  'get_xscale',
  'get_xticklabels',
  'get_zorder']

Suppose we want to customize the coordinates of a graph:

 x = np.linspace(0, 2, 100)
 
 fig, ax = plt.subplots()  # Create a figure and an axes.
 
 l1 = ax.plot(x, x, label="linear")
 l2 = ax.plot(x, x ** 2, label="quadratic")
 l3 = ax.plot(x, x ** 3, label="cubic")
 
 ax.set_title("Simple Plot")
 
 plt.show()

This is as simple as calling get_xticklabels on the axes object to get a list of Matplotlib Text instances:

 >>> ax.get_xticklabels()
 
 [Text(0, 0, 'Ideal'),
  Text(1, 0, 'Premium'),
  Text(2, 0, 'Very Good'),
  Text(3, 0, 'Good'),
  Text(4, 0, 'Fair')]

You can also adjust the tick marks with get_xticklines, or the position of the ticks with get_xticks.

The object has been obtained, and the following adjustments can be made

3、get / setp

Call the plt.getp function to view its current parameters. For example, suppose we want to style l2 of the following diagram:

 x = np.linspace(0, 2, 100)
 
 fig, ax = plt.subplots()  # Create a figure and an axes.
 
 l1 = ax.plot(x, x, label="linear")
 l2 = ax.plot(x, x ** 2, label="quadratic")
 l3 = ax.plot(x, x ** 3, label="cubic")
 
 ax.set_title("Simple Plot")
 
 plt.show()

This method returns all properties of the graph

 >>> plt.getp(l2)
     ...
     drawstyle or ds = default
     figure = Figure(640x480)
     linestyle or ls = -
     linewidth or lw = 1.5
     marker = None
     markeredgecolor or mec = #ff7f0e
     markeredgewidth or mew = 1.0
     markerfacecolor or mfc = #ff7f0e
     markerfacecoloralt or mfcalt = none
     zorder = 2
     ...

And plt.setp can change properties. Calling this on an object without any parameters will print out the property values ​​​​that the object can accept:

 >>> plt.setp(l2)
   ...
   linestyle or ls: {'-', '--', '-.', ':', '', (offset, on-off-seq), ...}
   linewidth or lw: float
   sketch_params: (scale: float, length: float, randomness: float)
   snap: bool or None
   zorder: float
   ...

To print the possible values ​​of a single attribute, the name of the attribute can be fed to setp as a string:

 >>> plt.setp(l2, "linestyle")
 linestyle: {'-', '--', '-.', ':', '', (offset, on-off-seq), ...}

The method of modifying properties is as follows:

 >>> plt.setp(l2, linestyle="-.", lw=5, color="red", alpha=0.5)
 [None, None, None, None]

To see the current figure after changes, just call get_figure on the figure object:

 fig.get_figure()

The style of the second row has changed

4、Legends

Legends can conveniently tell us the meaning of each component in the figure, which is displayed by default as follows:

 x = np.linspace(0, 2, 100)
 
 fig, ax = plt.subplots()  # Create a figure and an axes.
 
 l1 = ax.plot(x, x, label="linear")
 l2 = ax.plot(x, x ** 2, label="quadratic")
 l3 = ax.plot(x, x ** 3, label="cubic")
 
 ax.set_title("Simple Plot")
 
 ax.legend()
 
 plt.show()

We can adjust his parameters, for example:

Location of the legend, font properties, size, color, style, number of columns in the legend, etc.

It can be set before creation, or it can be extracted with get_legend after creation, and the getp and setp functions can be used.

5、cycler

Have you ever wondered how Matplotlib itself changes colors or cycles through different styles?

Under the hood, Matplotlib uses Python built-in objects called Cycles:

 from cycler import cycler
 
 c1 = cycler(arg1=[1, 2, 3, 4])
 >>> c1

This loop function takes any key-value argument and creates a list of dictionaries:

 c2 = cycler(arg2=list("rgba"))
 
 for i in c2:
     print(i)
 
 ------------------------------
 
 {'arg2': 'r'}
 {'arg2': 'g'}
 {'arg2': 'b'}
 {'arg2': 'a'}

It is also possible to combine multiple circulators with the "plus" and "multiply" operators, which allow index-by-index or exhaustive combinations of arguments:

 for i in c1 + c2:
     print(i)
 
 --------------------------------
 
 {'arg1': 1, 'arg2': 'r'}
 {'arg1': 2, 'arg2': 'g'}
 {'arg1': 3, 'arg2': 'b'}
 {'arg1': 4, 'arg2': 'a'}

You can customize the styling by taking this custom looper and passing it to Matplotlib. Below, we create four different line styles, allowing Matplotlib to cycle through different line colors, styles, and sizes:

 line_prop_cycler = (
     cycler(color=list("rgcy"))
     + cycler(ls=["-", "--", "-.", ":"])
     + cycler(lw=[3, 6, 9, 12])
 )

This custom cycler can be passed to the plot using the set_prop_cycle function of the axes object:

 x = np.linspace(0, 2 * np.pi, 50)
 offsets = np.linspace(0, 2 * np.pi, 4, endpoint=False)
 yy = np.transpose([np.sin(x + phi) for phi in offsets])
 
 fig, ax = plt.subplots(figsize=(8, 4))
 
 ax.set_prop_cycle(line_prop_cycler)  # Set propcycle before plotting
 ax.plot(x, yy)
 
 plt.show();

The default settings in the rcParams dictionary are as follows:

 rcParams["axes.prop_cycle"]

We can directly modify

6、tick_params

Axis scales should accurately communicate the minimum and maximum values ​​of data points and their units, and show a few key checkpoints for comparison between different plot sections.

Most tick attributes can be controlled using the tick_params function of the axes object. Here is an example from the documentation:

 >>> ax.tick_params()
 
 Parameters
 ----------
 axis : {'x', 'y', 'both'}, default: 'both'
     The axis to which the parameters are applied.
 which : {'major', 'minor', 'both'}, default: 'major'
     The group of ticks to which the parameters are applied.
 reset : bool, default: False
     Whether to reset the ticks to defaults before updating them.
 
 Other Parameters
 ----------------
 direction : {'in', 'out', 'inout'}
     Puts ticks inside the axes, outside the axes, or both.
 length : float
     Tick length in points.
 width : float
     Tick width in points.
 color : color
     Tick color.

The first two parameters that should be specified are axis and which. These parameters will be applied to the X or Y axis scale, as well as the minimum and maximum scale.

Most of the time, you won't see minor ticks in Matplotlib. You can use the minortics_on function on the axes object if you want:

 fig, ax = plt.subplots(figsize=(3, 2))
 
 >>> ax.minorticks_on()

7、Tickers

If not like a custom tick parameter (because it is very troublesome). A number of built-in Matplotlib collections of "themes" (called tickers) are available.

 from matplotlib import ticker
 dir(ticker)
 ['AutoLocator',
  'AutoMinorLocator',
  'EngFormatter',
  'FixedFormatter',
  'FixedLocator',
  'FormatStrFormatter',
  'Formatter',
  'FuncFormatter',
  'IndexFormatter',
  'IndexLocator',
  'Integral',
  'LinearLocator',
 ]

There are many such submodules under the ticker module. In general, controls with a Locator in the title control the position of the scale. Formatters represent the style of the label. After selection, you can use the following methods to set:

 from matplotlib.ticker import EngFormatter
 
 ax.xaxis.set_major_formatter(EngFormatter())

Using the xaxis or yaxis attribute of the axes object, call the set_major(minor)_formatter(locator) function and pass in the class name.

8、grid

Custom gridlines can highlight data ranges. In Matplotlib, grids can be created and customized using the grid function of the axes object. Here is an example of a vertical grid:

 fig, ax = plt.subplots()
 
 ax.grid(axis="x", linestyle=":", lw=3, color="r")

9、bar_label

Bar graphs are very common in data analysis. Their most important place is the height of each bar, and the bar label can highlight the display of each bar.

The bar_label function accepts a BarContainer object as a parameter and automatically labels the height of each bar.

Here is a simple count plot in Seaborn:

 import seaborn as sns
 
 diamonds = sns.load_dataset("diamonds")
 
 ax = sns.countplot(diamonds["cut"])

Every time a barplot is created using a function such as Seaborn or ax.bar, a BarContainer object is added to the figure. This container object can be retrieved using the containers property of the axes object:

 ax.containers
 [<BarContainer object of 5 artists>]

In the above list there is a BarContainer object with 5 bars. We just pass this object to bar_label after creating the plot:

 ax = sns.countplot(diamonds["cut"])
 ax.bar_label(ax.containers[0], padding=1)
 ax.set_ylim(0, 25000)
 plt.show();

10、zorder

When there are many graphs, the display order is very important. You need to ensure that each shape is drawn in the proper order on the canvas, you need the zorder parameter.

Below, we create three rows with different zorders:

 x = np.linspace(0, 7.5, 100)
 
 plt.plot(x, np.sin(x), label="zorder=2", zorder=2)  # bottom
 plt.plot(x, np.sin(x + 0.5), label="zorder=3", zorder=3)
 plt.axhline(0, label="zorder=2.5", color="lightgrey", zorder=2.5)
 
 plt.title("Custom order of elements")
 
 l = plt.legend(loc="upper right")
 l.set_zorder(2.5)  # legend between blue and orange line
 
 plt.show()

It can be seen that the larger the zorder, it will be displayed at the top, covering small components.

Summarize

Matplotlib has more than 30 million downloads in June 2023, almost 4 times that of its biggest competitor, Plotly. The success of Matplotlib lies not only in its simplicity (it only needs a few lines of code to generate simple graphics), but also in its powerful functions, but to use these powerful functions, you need to use his advanced functions, but these advanced functions often For more complex configuration or parameters, we need to browse the official documents. That's why seaborn appeared. He integrated Matplotlib not only simple but also beautiful.

But sometimes we need more in-depth customization functions, seaborn may not reach our goal, we can only define parameters by ourselves, this article summarizes an advanced technique that can easily help you completely customize Matplotlib tasks.

https://avoid.overfit.cn/post/fece2cde8dbd4f899de00f5509385c6c

Author: Bex T

Guess you like

Origin blog.csdn.net/m0_46510245/article/details/131498077