Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Bug]: LaTeX option clash error when pgf.preamble uses certain packages #28213

Copy link
Copy link
Open
@voidstarstar

Description

@voidstarstar
Issue body actions

Bug summary

I think in LaTeX, if \usepackage is called multiple times for the same package, it is only actually loaded on the first call. Any desired options must be included in this first call. If a subsequent call contains different options, it will cause an "option clash" error. If a subsequent call contains no options, it will not cause this error and will silently be ignored.

Given the above mechanics, there is a bug in matplotlib. Matplotlib needs certain packages (hyperref, geometry, etc.), but there is no way to know if the user defined custom preamble (pgf.preamble) will also includes these. Currently, matplotlib loads some of these packages before and some after the custom preamble.

To reproduce the bug, a custom preamble can be created that loads all of the packages that matplotlib depends on, but passes different options to them.

Code for reproduction

import matplotlib.pyplot as plt
import matplotlib as mpl

mpl.use('pgf')
preamble = '\n'.join([
    r'\usepackage[no-math]{fontspec}',
    r'\usepackage[nohyphen]{underscore}',
    r'\usepackage[demo]{graphicx}',
    r'\usepackage[draft]{hyperref}',
    r'\usepackage[margin=1in]{geometry}',
    r'\usepackage[draft]{pgf}',
    r'\usepackage[ascii]{inputenc}',
    r'\usepackage[safe]{textcomp}',
    ])
mpl.rcParams['pgf.preamble'] = preamble

# Define the x and y data
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]

# Create a figure and axis object
fig, ax = plt.subplots()

# Plot the data
ax.plot(x, y)

# Set the title and axis labels
ax.set_title('Line Plot')
ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')

# Save the plot as a PNG file
plt.savefig('plot.png')

Actual outcome

Matplotlib crashes because the LaTeX compiler produces an option clash error.

Expected outcome

Matplotlib will use the user defined options, but override them when applicable.

Additional information

Solution:

This problem can be solved using the \PassOptionsToPackage command. This command can contain the options that matplotlib requires and be called prior to the custom preamble in a pre-processing phase. Then after the custom preamble, the package can be loaded by calling \usepackage without any options in a post-processing phase.

There are 2 possible outcomes:

  1. The custom preamble does not contain the package. In this case, the post-processing phase loads the package by appending the options stated in the pre-processing phase.
  2. The custom preamble contains the package. In this case, the package will be loaded in the custom preamble by appending the options stated in the pre-processing phase. Then the post-processing phase is silently ignored.

Note: When matplotlib loads packages after the custom preamble and without any options (such as fontspec), no error will occur, so the code is fine as it is.

This issue is solved by #28167.

Operating system

Ubuntu

Matplotlib Version

3.7.5

Matplotlib Backend

pgf

Python version

3.8

Jupyter version

No response

Installation

pip

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.