Default plot line colors are now dull (after upgrade matplotlib 3.4.3 to 3.5.2). How do I change it back?

I’m an engineer and have been making .pdf plot packages of various test data with the same format auto-generated python code. I’ve been using matplotlib v3.4.3 with Python 3.10. I read about improvements in the next releases of matplotlib such as better loc=“best” placement of the legends (which it does improve by the way), so I upgraded. However, I was disappointed to find that all the colors for the lines are now very dull and more difficult to see the differences compared to the vibrant colors in v3.4.3. I tried both matplotlib v3.5.2 and v3.6.0 and they are dull, then rolled back to v3.4.3 and they are vibrant again. I define the colors using hex codes in my plot command: (example: color =‘#0000FF’; color =‘#00FF00’; color =‘#FF0000’; etc).

Is there any way to globally change the default set of colors back to the way they were on the new version? I apologize if this is obvious, but I’ve been stumbling around trying various things with the matplotlibrc and putting various commands I found on forums as the top of my .py file.

It doesn’t look horrible because I’m zoomed in so you can see, but zoomed out it can be really hard to differentiate the colors.

Line colors on v3.4.2:
image

Line colors on v3.5.3 and v3.6.0:
image

Thanks

Can you give us a code example to reproduce this?

If we are converting HEX codes differently that would indeed be a major problem, but I think we need more information to debug this.

Thank you for your response.
I’ll see if I can get something simple so you can reproduce easily, but for right now, this is a short segment of my code below.

color =‘#0000FF’ should be the normal bright blue
color =‘#00FF00’ should be the normal bright green

Looks normal when I have this one installed:
matplotlib-3.4.3-cp310-cp310-win_amd64.whl

On these versions, those colors are dull and not expected:
matplotlib-3.5.2-cp310-cp310-win_amd64.whl
matplotlib-3.6.0-cp310-cp310-win_amd64.whl

import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.pyplot import figure
import matplotlib.gridspec as gridspec
from mpl_toolkits.axes_grid1 import host_subplot
from matplotlib.backends.backend_pdf import PdfPages
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator, MaxNLocator)
import matplotlib.transforms as MT
from matplotlib.ticker import FormatStrFormatter

df1 = pd.read_csv("data_set.csv")

fig1= plt.figure (1, figsize = (12,8))
gs = gridspec.GridSpec(nrows=2, ncols=1)
fig1.suptitle('redacted_plot_title', fontsize = 16)

plot1 = host_subplot (gs[0])
plot1.set_xlabel ('TIME')
plot1.plot (df1['time'], df1['param_1-tv'], label = 'PARAM_1-TV', color ='#0000FF', marker = 'o', **marker_style)
plot1 = custom_spine (True, plot1 , plot1, fig1, 'PARAM_1', -1, 9, 0, False)

plot1b = plot1.twinx()
plot1b.plot (df1['time'], df1['param_2-tv'], label = 'PARAM_2-TV', color ='#00FF00', marker = 's', **marker_style)
plot1b = custom_spine (False, plot1, plot1b, fig1, 'PARAM_2', -100, 400, 1, False)

plot1.legend (loc = 'best', bbox_to_anchor=(0,0,1,1), bbox_transform=plot1.transAxes, fontsize=8)
plot1.set_xlim(0,120)
plt.locator_params(axis='x', nbins=12)
pp.savefig(fig1)

I took the liberty of adding markup so it would render as Python.

I do not see marker_style defined, I suspect that will be key to sorting this out.

Can you cut this down to an example we can copy-paste-run? Hopefully this issue can be reproduced with random data.

I apologize, my full generated .py files are very long (~10,000 lines) to produce a few hundred pages of plots. I just tried taking a sample, and I’m also trying to be careful as this is something I’m doing for my job and don’t want to share actual data names, etc.

Therefore, I missed the marker_style.
It was in fact included in my code.
I also have code at the top to define the custom_spine.
I’ll throw that all in here.

Going to see if I can reproduce with random generated data and share with you.

import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.pyplot import figure
import matplotlib.gridspec as gridspec
from mpl_toolkits.axes_grid1 import host_subplot
from matplotlib.backends.backend_pdf import PdfPages
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator, MaxNLocator)
import matplotlib.transforms as MT
from matplotlib.ticker import FormatStrFormatter

mpl.rcParams['axes.linewidth'] = .5
mpl.rcParams['lines.linewidth'] = 1
mpl.rcParams['patch.linewidth'] = .5
mpl.rcParams['legend.title_fontsize'] = 10

marker_style = dict (markersize = 5, markeredgecolor = '#000000', markevery = 2000)

def custom_spine (isitfirst, orig_plt, cur_plot, fig, ylabel, ymin, ymax, yaxescount, fingraphs):
	if isitfirst == True:
		spineplot = orig_plt
		spineplot.set_frame_on(True)
		spineplot.patch.set_visible(False)
		spineplot.set_ylabel (ylabel, labelpad = 5, fontsize = 5)
		spineplot.grid(True,which = 'major', color = 'grey')
		plt.xticks(fontsize = 5)
		plt.yticks(fontsize = 5, va = 'center')
		plt.figtext (.15, .06, 'Wed Oct 19 2022', va='baseline', ha='center', wrap=True)
		plt.figtext (.15, .03, '18:22:43', va='baseline', ha='center', wrap=True)
		plt.figtext (.35, .06, 'Python Version:', va='baseline', ha='center', wrap=True)
		plt.figtext (.35, .03, '3.10.0', va='baseline', ha='center', wrap=True)
		plt.figtext (.6, .06, 'Macro:', va='baseline', ha='center', wrap=True)
		plt.figtext (.6, .03, 'python_output.py', va='baseline', ha='center', wrap=True)
		spineplot.tick_params(axis='y', which='both', direction ='in', pad=5)
		spineplot.tick_params(axis='x', which='both', direction ='in', pad=2)
	elif isitfirst == False:
		spineplot = cur_plot
		yaxespos = (yaxescount*-0.09)
		spineplot.spines['right'].set_position(('axes', yaxespos))
		spineplot.yaxis.tick_right()
		spineplot.set_ylabel (ylabel, labelpad = -40, fontsize = 5)
		spineplot.tick_params (axis ='y', direction = 'out')
		plt.setp(spineplot.get_yticklabels(), fontsize = 5, ha = 'right')
		dx = 10/72.; dy = 0/72.
		offset = MT.ScaledTranslation(dx, dy, fig.dpi_scale_trans)
		for label in spineplot.get_yticklabels(): 
			label.set_transform(label.get_transform() - offset)
	else:
		spineplot = cur_plot
		spineplot.axes.get_yaxis().set_visible(False)
	if yaxescount != []:
		leftloc = (0.10 +(0.05*yaxescount))
		plt.subplots_adjust(left = leftloc, right = 0.90, bottom = 0.15)
	if fingraphs == True:
		spineplot.yaxis.set_major_locator(MultipleLocator(5))
		spineplot.set_ylabel (ylabel, labelpad = 5, fontsize = 10)
	else:
		increment = (ymax-ymin)/10
		spineplot.yaxis.set_ticks(np.arange(ymin, ymax*1.000001, increment))
	spineplot.set_ylim(ymin, ymax)
	spineplot.yaxis.set_minor_locator(AutoMinorLocator(10))
	spineplot.xaxis.set_minor_locator(AutoMinorLocator(10))
	spineplot.yaxis.set_major_formatter(FormatStrFormatter('%.1f'))
	spineplot.tick_params(axis='x', which='both', direction ='in', pad=2)
	return spineplot

pp = PdfPages('plot_output.pdf')

df1 = pd.read_csv("data_set.csv")

fig1= plt.figure (1, figsize = (12,8))
gs = gridspec.GridSpec(nrows=2, ncols=1)
fig1.suptitle('plot_title', fontsize = 16)

plot1 = host_subplot (gs[0])
plot1.set_xlabel ('TIME')
plot1.plot (df1['time'], df1['param_1-tv'], label = 'PARAM_1-TV', color ='#0000FF', marker = 'o', **marker_style)
plot1 = custom_spine (True, plot1 , plot1, fig1, 'PARAM_1', -1, 9, 0, False)

plot1b = plot1.twinx()
plot1b.plot (df1['time'], df1['param_2-tv'], label = 'PARAM_2-TV', color ='#00FF00', marker = 's', **marker_style)
plot1b = custom_spine (False, plot1, plot1b, fig1, 'PARAM_2', -100, 400, 1, False)

plot1.legend (loc = 'best', bbox_to_anchor=(0,0,1,1), bbox_transform=plot1.transAxes, fontsize=8)
plot1.set_xlim(0,120)
plt.locator_params(axis='x', nbins=12)
pp.savefig(fig1)

Ok, I have code you can run below.

matplotlib 3.4.3: matplotlib-3.4.3-cp310-cp310-win_amd64.whl

matplotlib v3.6.0: matplotlib-3.6.0-cp310-cp310-win_amd64.whl

#Created on: Thur_Oct_20_14:13:22_2022
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.pyplot import figure
import matplotlib.gridspec as gridspec
from mpl_toolkits.axes_grid1 import host_subplot
from matplotlib.backends.backend_pdf import PdfPages
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator, MaxNLocator)
import matplotlib.transforms as MT
from matplotlib.ticker import FormatStrFormatter

mpl.rcParams['axes.linewidth'] = .5
mpl.rcParams['lines.linewidth'] = 1
mpl.rcParams['patch.linewidth'] = .5
mpl.rcParams['legend.title_fontsize'] = 10

marker_style = dict (markersize = 5, markeredgecolor = '#000000', markevery = 1)
def custom_spine (isitfirst, orig_plt, cur_plot, fig, ylabel, ymin, ymax, yaxescount, fingraphs):
	if isitfirst == True:
		spineplot = orig_plt
		spineplot.set_frame_on(True)
		spineplot.patch.set_visible(False)
		spineplot.set_ylabel (ylabel, labelpad = 5, fontsize = 5)
		spineplot.grid(True,which = 'major', color = 'grey')
		plt.xticks(fontsize = 5)
		plt.yticks(fontsize = 5, va = 'center')
		plt.figtext (.15, .06, 'Wed Oct 19 2022', va='baseline', ha='center', wrap=True)
		plt.figtext (.15, .03, '18:22:43', va='baseline', ha='center', wrap=True)
		plt.figtext (.35, .06, 'Python Version:', va='baseline', ha='center', wrap=True)
		plt.figtext (.35, .03, '3.10.0', va='baseline', ha='center', wrap=True)
		plt.figtext (.6, .06, 'Macro:', va='baseline', ha='center', wrap=True)
		plt.figtext (.6, .03, 'test.py', va='baseline', ha='center', wrap=True)
		spineplot.tick_params(axis='y', which='both', direction ='in', pad=5)
		spineplot.tick_params(axis='x', which='both', direction ='in', pad=2)
	elif isitfirst == False:
		spineplot = cur_plot
		yaxespos = (yaxescount*-0.09)
		spineplot.spines['right'].set_position(('axes', yaxespos))
		spineplot.yaxis.tick_right()
		spineplot.set_ylabel (ylabel, labelpad = -40, fontsize = 5)
		spineplot.tick_params (axis ='y', direction = 'out')
		plt.setp(spineplot.get_yticklabels(), fontsize = 5, ha = 'right')
		dx = 10/72.; dy = 0/72.
		offset = MT.ScaledTranslation(dx, dy, fig.dpi_scale_trans)
		for label in spineplot.get_yticklabels(): 
			label.set_transform(label.get_transform() - offset)
	else:
		spineplot = cur_plot
		spineplot.axes.get_yaxis().set_visible(False)
	if yaxescount != []:
		leftloc = (0.10 +(0.05*yaxescount))
		plt.subplots_adjust(left = leftloc, right = 0.90, bottom = 0.15)
	if fingraphs == True:
		spineplot.yaxis.set_major_locator(MultipleLocator(5))
		spineplot.set_ylabel (ylabel, labelpad = 5, fontsize = 10)
	else:
		increment = (ymax-ymin)/10
		spineplot.yaxis.set_ticks(np.arange(ymin, ymax*1.000001, increment))
	spineplot.set_ylim(ymin, ymax)
	spineplot.yaxis.set_minor_locator(AutoMinorLocator(10))
	spineplot.xaxis.set_minor_locator(AutoMinorLocator(10))
	spineplot.yaxis.set_major_formatter(FormatStrFormatter('%.1f'))
	spineplot.tick_params(axis='x', which='both', direction ='in', pad=2)
	return spineplot

pp = PdfPages('plot_output.pdf')

fig1= plt.figure (1, figsize = (12,8))
gs = gridspec.GridSpec(nrows=2, ncols=1)
fig1.suptitle('PLOT_TITLE', fontsize = 16)

plot1 = host_subplot (gs[0])
plot1.set_xlabel ('TIME')
plot1.plot ([0, 1, 2, 3, 4, 5], [1, 1, 4, 4, 2, 2], label = 'PARAM_1-TVA', color ='#0000FF', marker = 'o', **marker_style)
plot1 = custom_spine (True, plot1 , plot1, fig1, 'PARAM_1', -1, 9, 0, False)

plot1b = plot1.twinx()
plot1b.plot ([0, 1, 2, 3, 4, 5], [50, 252, 210, 102, 108, 300], label = 'PARAM_2-TVA', color ='#00FF00', marker = 's', **marker_style)
plot1b = custom_spine (False, plot1, plot1b, fig1, 'PARAM_2...PARAM_3', -100, 400, 1, False)

plot1c = plot1.twinx()
plot1c.plot ([0, 1, 2, 3, 4, 5], [50, 80, 80, 30, 40, 40], label = 'PARAM_3-TVA', color ='#FF0000', marker = '^', **marker_style)
plot1c = custom_spine (False, plot1, plot1c, fig1, 'PARAM_2...PARAM_3', -100, 400, 1, False)

plot1.legend (loc = 'best', bbox_to_anchor=(0,0,1,1), bbox_transform=plot1.transAxes, fontsize=8)
plot1.set_xlim(0,5)

plot2 = host_subplot (gs[1])
plot2.set_xlabel ('TIME')
plot2.plot ([0, 1, 2, 3, 4, 5], [1, 1, 4, 4, 2, 2], label = 'PARAM_1-TVB', color ='#FF00FF', marker = 'o', **marker_style)
plot2 = custom_spine (True, plot2 , plot2, fig1, 'PARAM_1', -1, 9, 0, False)

plot2b = plot2.twinx()
plot2b.plot ([0, 1, 2, 3, 4, 5], [50, 252, 210, 102, 108, 300], label = 'PARAM_2-TVB', color ='#009FFF', marker = 's', **marker_style)
plot2b = custom_spine (False, plot2, plot2b, fig1, 'PARAM_2...PARAM_3', -100, 400, 1, False)

plot2c = plot2.twinx()
plot2c.plot ([0, 1, 2, 3, 4, 5], [50, 80, 80, 30, 40, 40], label = 'PARAM_3-TVB', color ='#FFDF00', marker = '^', **marker_style)
plot2c = custom_spine (False, plot2, plot2c, fig1, 'PARAM_2...PARAM_3', -100, 400, 1, False)

plot2.legend (loc = 'best', bbox_to_anchor=(0,0,1,1), bbox_transform=plot2.transAxes, fontsize=8)
plot2.set_xlim(0,5)

plt.locator_params(axis='x', nbins=12)
pp.savefig(fig1)
pp.close()

Interesting …
matplotlib v3.6.0 with
Adobe Acrobat X Pro 10.1.16
colors look fine in simpler code example

import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.pyplot import figure
import matplotlib.gridspec as gridspec
from mpl_toolkits.axes_grid1 import host_subplot
from matplotlib.backends.backend_pdf import PdfPages
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator, MaxNLocator)
import matplotlib.transforms as MT
from matplotlib.ticker import FormatStrFormatter

marker_style = dict (markersize = 5, markeredgecolor = '#000000', markevery = 1)

pp = PdfPages('plot_output.pdf')

fig, ax = plt.subplots()
ax.plot(range(5), color='#00FF00')
ax.plot(range(5)[::-1], color='#0000FF')

pp.savefig(fig)
pp.close()

I found the culprit line of code:
ax.legend (loc = ‘best’, bbox_to_anchor=(0,0,1,1), bbox_transform=ax.transAxes, fontsize=8)

If I keep that line in, it looks like this

If I remove that line it looks like this:

Again, this is only the case for versions after matplotlib v3.4.3.
Both look the same on matplotlib v3.5.2.

import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.pyplot import figure
import matplotlib.gridspec as gridspec
from mpl_toolkits.axes_grid1 import host_subplot
from matplotlib.backends.backend_pdf import PdfPages
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator, MaxNLocator)
import matplotlib.transforms as MT
from matplotlib.ticker import FormatStrFormatter
	
pp = PdfPages('plot_output.pdf')

fig, ax = plt.subplots()
ax.plot(range(5), label = 'PARAM_1-TVA', color='#00FF00')
ax.plot(range(5)[::-1], label = 'PARAM_2-TVA', color='#0000FF')

ax.legend (loc = 'best', bbox_to_anchor=(0,0,1,1), bbox_transform=ax.transAxes, fontsize=8)
ax.set_xlim(0,5)

pp.savefig(fig)
pp.close()

I cannot reproduce with Reader 22.3.20258.0. Maybe a bug in your particular Acrobat version?

Yeah something has changed in the new version of matplotlib to make the colors come out odd in some pdf viewers (probably older ones). I’m using the latest version of Adobe Acrobat X Pro (10.1.16), which is quite dated now, but it’s the one I have a license for.

import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
mpl.rcParams['pdf.compression'] = 0 

pp = PdfPages(f"/tmp/plot_output_{mpl.__version__}.pdf")

fig, ax = plt.subplots()
ax.plot(range(5), label="PARAM_1-TVA", color="#00FF00")
ax.plot(range(5)[::-1], label="PARAM_2-TVA", color="#0000FF")

ax.legend(
    loc="best", bbox_to_anchor=(0, 0, 1, 1), bbox_transform=ax.transAxes, fontsize=8
)
ax.set_xlim(0, 5)

pp.savefig(fig)
pp.close()

Using the above code (removed un-needed imports, ran through black, and turned off pdf compression. Diffing the file from 3.4.3 and 3.5.3 gives

--- /tmp/plot_output_3.4.3.pdf	2022-10-21 08:43:32.874864263 -0400
+++ /tmp/plot_output_3.5.3.pdf	2022-10-21 08:48:11.495072581 -0400
@@ -9,13 +9,14 @@
 /XObject 7 0 R >>
 endobj
 11 0 obj
-<< /Annots 10 0 R /Contents 9 0 R
-/Group << /CS /DeviceRGB /S /Transparency /Type /Group >>
-/MediaBox [ 0 0 460.8 345.6 ] /Parent 2 0 R /Resources 8 0 R /Type /Page >>
+<< /Annots 10 0 R /Contents 9 0 R /MediaBox [ 0 0 460.8 345.6 ]
+/Parent 2 0 R /Resources 8 0 R /Type /Page >>
 endobj
 9 0 obj
 << /Length 12 0 R >>
 stream
+/DeviceRGB CS
+/DeviceRGB cs
 1 j
 1 g 0 j 0 w 1 G 1 g
 0 0 m
@@ -279,6 +280,7 @@
 B
 /A2 gs 2 J 1 j 1.5 w 0 1 0 RG /DeviceRGB cs
 331.198125 177.762625 m
+339.198125 177.762625 l
 347.198125 177.762625 l

 S
@@ -292,6 +294,7 @@
 Q
 2 J 1.5 w 0 0 1 RG /DeviceRGB cs
 331.198125 165.793875 m
+339.198125 165.793875 l
 347.198125 165.793875 l

 S
@@ -308,7 +311,7 @@
 endstream
 endobj
 12 0 obj
-3239
+3315
 endobj
 10 0 obj
 [ ]
@@ -662,19 +665,19 @@
 endstream
 endobj
 15 0 obj
-<< /BaseFont /DejaVuSans /CharProcs 16 0 R
+<< /BaseFont /BMQQDV+DejaVuSans /CharProcs 16 0 R
 /Encoding <<
 /Differences [ 45 /hyphen /period 48 /zero /one /two /three /four /five 65 /A 77 /M 80
 /P 82 /R 84 /T 86 /V 95 /underscore ]
 /Type /Encoding >>
 /FirstChar 0 /FontBBox [ -1021 -463 1794 1233 ] /FontDescriptor 14 0 R
-/FontMatrix [ 0.001 0 0 0.001 0 0 ] /LastChar 255 /Name /DejaVuSans
+/FontMatrix [ 0.001 0 0 0.001 0 0 ] /LastChar 255 /Name /BMQQDV+DejaVuSans
 /Subtype /Type3 /Type /Font /Widths 13 0 R >>
 endobj
 14 0 obj
 << /Ascent 929 /CapHeight 0 /Descent -236 /Flags 32
-/FontBBox [ -1021 -463 1794 1233 ] /FontName /DejaVuSans /ItalicAngle 0
-/MaxWidth 1342 /StemV 0 /Type /FontDescriptor /XHeight 0 >>
+/FontBBox [ -1021 -463 1794 1233 ] /FontName /BMQQDV+DejaVuSans
+/ItalicAngle 0 /MaxWidth 1342 /StemV 0 /Type /FontDescriptor /XHeight 0 >>
 endobj
 13 0 obj
 [ 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600
@@ -718,47 +721,47 @@
 << /Count 1 /Kids [ 11 0 R ] /Type /Pages >>
 endobj
 32 0 obj
-<< /CreationDate (D:20221021084332-04'00')
-/Creator (Matplotlib v3.4.3, https://matplotlib.org)
-/Producer (Matplotlib pdf backend v3.4.3) >>
+<< /CreationDate (D:20221021084811-04'00')
+/Creator (Matplotlib v3.5.3, https://matplotlib.org)
+/Producer (Matplotlib pdf backend v3.5.3) >>
 endobj
 xref
 0 33
 0000000000 65535 f
 0000000016 00000 n
-0000010564 00000 n
-0000010327 00000 n
-0000010359 00000 n
-0000010501 00000 n
-0000010522 00000 n
-0000010543 00000 n
+0000010603 00000 n
+0000010366 00000 n
+0000010398 00000 n
+0000010540 00000 n
+0000010561 00000 n
+0000010582 00000 n
 0000000065 00000 n
-0000000392 00000 n
-0000003706 00000 n
+0000000334 00000 n
+0000003724 00000 n
 0000000208 00000 n
-0000003685 00000 n
-0000009066 00000 n
-0000008866 00000 n
-0000008465 00000 n
-0000010119 00000 n
-0000003726 00000 n
-0000003924 00000 n
-0000004130 00000 n
-0000004510 00000 n
-0000005021 00000 n
-0000005181 00000 n
-0000005328 00000 n
-0000005875 00000 n
-0000006108 00000 n
-0000006233 00000 n
-0000006422 00000 n
-0000006545 00000 n
-0000007288 00000 n
-0000007829 00000 n
-0000007962 00000 n
-0000010624 00000 n
+0000003703 00000 n
+0000009105 00000 n
+0000008898 00000 n
+0000008483 00000 n
+0000010158 00000 n
+0000003744 00000 n
+0000003942 00000 n
+0000004148 00000 n
+0000004528 00000 n
+0000005039 00000 n
+0000005199 00000 n
+0000005346 00000 n
+0000005893 00000 n
+0000006126 00000 n
+0000006251 00000 n
+0000006440 00000 n
+0000006563 00000 n
+0000007306 00000 n
+0000007847 00000 n
+0000007980 00000 n
+0000010663 00000 n
 trailer
 << /Info 32 0 R /Root 1 0 R /Size 33 >>
 startxref
-10781
+10820
 %%EOF

Here are the 3 pdfs I generated:

plot_output_3.5.3.pdf (11.3 KB)
plot_output_3.6.1.pdf (11.3 KB)
plot_output_3.4.3.pdf (11.3 KB)

There are bigger changes between 3.5 and 3.6 than between 3.4 and 3.5.

Unfortunately I do not know the pdf language well enough to understand what is wrong, but

-/Group << /CS /DeviceRGB /S /Transparency /Type /Group >>

or

+/DeviceRGB CS
+/DeviceRGB cs

are the most suspicious things to me.

We have also exposed bugs in renderers before (the most recent one was clipboxes in rsvg) so it is very possible that all three versions are correct with in the spec and that one version of adobe has a rendering bug…

Two new theories:

  1. Does the version of Adobe that looks wrong have any sort of color correction set up? Per https://opensource.adobe.com/dc-acrobat-sdk-docs/standards/pdfstandards/pdf/PDF32000_2008.pdf section 8.6 colour is complicated. Maybe those extra /DeviceRGB is opting-in and the color correction is “helping”?
  2. The alpha from the legend is “leaking” to the lines. If you pass framealpha=1 to the call to legend does that fix things?

tacaswell,
Sorry it took a while for me to get back to you.
Adobe Acrobat color settings are set correctly as far as I know.
I just tried passing framealpha=1 to the legend like you said, and it fixed the problem.
So the code below, removing framealpha=1 and the colors don’t look right, but with framealpha=1 they look normal. This is on v3.6.0.

That’s a good enough solution for me for now!
Thank you so much!

import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.pyplot import figure
import matplotlib.gridspec as gridspec
from mpl_toolkits.axes_grid1 import host_subplot
from matplotlib.backends.backend_pdf import PdfPages
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator, MaxNLocator)
import matplotlib.transforms as MT
from matplotlib.ticker import FormatStrFormatter
	
pp = PdfPages('plot_output.pdf')

fig, ax = plt.subplots()
ax.plot(range(5), label = 'PARAM_1-TVA', color='#00FF00')
ax.plot(range(5)[::-1], label = 'PARAM_2-TVA', color='#0000FF')

ax.legend (loc = 'best', bbox_to_anchor=(0,0,1,1), bbox_transform=ax.transAxes, fontsize=8, framealpha=1)
ax.set_xlim(0,5)

pp.savefig(fig)
pp.close()
1 Like

Great!

I think this leaves us with one of two things being the case:

  1. we are out putting out-of-spec PDFs, but all but one viewers are “helping”
  2. The PDF viewer the OP was using was buggy and leaking the alpha state

Given that the issue was only seen with one viewer, I’m inclined to go with option 2 and consider this closed from our side as well.