I would like to define a standard matplotlib style using a matplotlibrc file, with the plot legend outside the plot. This is possible using bbox_to_anchor in the plot code, but this is not a known rcparam. Any other options?
Is it possible to make all plot titles appear in capitals using matplotlibrc?
Asked
Active
Viewed 129 times
2

Karen
- 47
- 4
-
The [answer here](https://stackoverflow.com/questions/3439344/setting-spines-in-matplotlibrc) seems useful for figuring out what can be controlled by matplotlibrc and what can't. I haven't checked for bbox_to_anchor and uppercasing, though. – cphlewis Jan 24 '22 at 19:42
-
If the answer without bbox_to_anchor was useful, this question might be more useful with a different title. "Automatically plot with a legend outside the plot"? "Enforcing plot styles without rcParams"? – cphlewis Feb 01 '22 at 01:35
1 Answers
2
Short answer is that neither of those things can be set in rcParams. You can get the sidebar-legend by passing a tuple as the loc
argument to legend()
, but rcParams can't handle tuple values yet. And I don't think rcParams is the right place to do text modification like uppercasing.
You can put both into a decorator, along with rcParams, and have a decorated version of pyplot calls:
import matplotlib.pyplot as plt
import matplotlib as mpl
xs, x2s, ys = [4,1,3,5,2], [1,2,3,4,5], [2,3,1,2,-1]
def house_style(func):
def sidelegend_wrapper(*args, **kwargs):
title = kwargs.pop('title', None)
with plt.style.context('dark_background'): #or your rcParams
func(*args, **kwargs)
cf = plt.gcf()
cf.subplots_adjust(right=0.7)
cax = plt.gca()
if title: cax.set_title(title.upper())
cax.legend(loc=(1.1, .8))
return(sidelegend_wrapper)
@house_style
def decorated_scatter(*args, **kwargs):
plt.scatter(*args, **kwargs)
@house_style
def decorated_plot(*args, **kwargs):
plt.plot(*args, **kwargs)
decorated_scatter(xs, ys, label='decorator', title='lowercase')
decorated_plot(x2s, ys, label='also dec')
Result:
If I needed to plot into specific axes instead of using pyplot
I would put that and what just went into the decorator into a function:
def our_function(*args, **kwargs):
title = kwargs.pop('title', None)
sc_data = kwargs.pop('sc_data', None)
line_data = kwargs.pop('line_data', None)
fig, axs= plt.subplots(2)
fig.subplots_adjust(right=0.7)
axs[0].scatter(sc_data[0],sc_data[1], **kwargs)
axs[1].plot(line_data[0], line_data[1], **kwargs)
if title: fig.suptitle(title.upper())
axs[0].legend(loc=(1.1,.5))
our_function(sc_data = [xs, ys], line_data=[x2s, ys], label='function', title='lowercase\nwell, it was')
plt.show()
That one doesn't call rcParams but could, just like the decorators.
Possibly one could decorate the Axes
class itself so that every instance had decorated plotting functions?

cphlewis
- 15,759
- 4
- 46
- 55