Convenient plotting wrapper around matplotlib.
Project description
MatChart
MatChart is a convenient one-line wrapper around matplotlib plotting library.
Usage
from matchart import plot
plot([x1, y1], [y2], [x3, y3], y4, ...,
# common parameters
kind='plot',
show: bool = True,
block: Optional[bool] = None,
context: bool = False,
# plotter explict parameters
label: ClippedArguments = None,
color: CycledArguments = None,
marker: ClippedArguments = None,
linestyle: ClippedArguments = None,
linewidth: ClippedArguments = None,
markersize: ClippedArguments = None,
# figure and axes parameters
legend: Optional[bool] = None,
legend_kwargs: Optional[Dict[str, Any]] = None,
title: Optional[str] = None,
title_kwargs: Optional[Dict[str, Any]] = None,
xlabel: Optional[str] = None,
xlabel_kwargs: Optional[Dict[str, Any]] = None,
ylabel: Optional[str] = None,
ylabel_kwargs: Optional[Dict[str, Any]] = None,
limit: Union[Tuple[Any, Any, Any, Any], bool] = True,
figsize: Tuple[float, float] = (10, 8),
dpi: float = 100,
subplots_kwargs: Optional[Dict[str, Any]] = None,
grid: Optional[bool] = False,
grid_kwargs: Optional[Dict[str, Any]] = None,
theme = 'seaborn-v0_8-deep',
# plotter rest parameters
** plotter_kwargs #
) -> Tuple[Figure, Axes, List[Artist]]
kind
- pyplot function name, e.g. plot or scatter.
show
- whether to show plot or just to draw it.
block
- whether to block running code when showing plot or just display windows and run next lines. By default, detected from environment.
context
- delay showing plot by using context manager (see below).
label
, color
, marker
, linestyle
, linewidth
, markersize
and rest plotter_kwargs
- plotter parameters. Can differ per kind. See common parameters for kind='plot'
. Can be list
or tuple
to define per-dataset values. Values can also be None
or even clipped to skip definition for particular dataset.
legend
- set True
, False
or None
to autodetect. legend_kwargs
- additional parameters.
title
- plot's title. title_kwargs
- additional parameters.
xlabel
- horizontal axis label. xlabel_kwargs
- additional parameters.
ylabel
- vertical axis label. ylabel_kwargs
- additional parameters.
limit
- set True
to autodetect 2D plot's borders or False
to use default matplot's behaviour. Set to (left, right, bottom, top)
to use custom borders.
figsize
- plot's size as (width, height)
in inches. By default, is overriden with 10x8.
dpi
- plot's resolution in dots-per-inch.
subplots_kwargs
- additional plot's parameters and Figure's parameters.
grid
- plot's grid visibility with grid_kwargs
as additional parameters.
theme
- plot's style. By default is overriden with seaborn-v0_8-deep.
Examples
Just plot something
Firstly prepare data:
import numpy as np
x1 = np.arange(21)
y1 = x1 ** 2
y2 = x1 ** 1.9
x3 = 5, 15
y3 = 300, 100
y4 = x1 ** 2.1
Then plot data:
from matchart import plot
plot([x1, y1], [y2], [x3, y3], y4,
label=['$x^{2}$', '$x^{1.9}$', 'Points'],
xlabel='X', ylabel='Y',
title='Power of $x$ comparison.',
grid=True,
color=[None, 'green', 'red', 'gray'],
marker=['o', None, '*'],
linestyle=[None, '--'],
linewidth=[None, 3, 0],
markersize=20,
fillstyle='top')
Migrate from matplotlib simple
Let's take FiveThirtyEight style sheet example:
import matplotlib.pyplot as plt
import numpy as np
plt.style.use('fivethirtyeight')
x = np.linspace(0, 10)
np.random.seed(19680801) # Fixing random state for reproducibility
fig, ax = plt.subplots()
ax.plot(x, np.sin(x) + x + np.random.randn(50))
ax.plot(x, np.sin(x) + 0.5 * x + np.random.randn(50))
ax.plot(x, np.sin(x) + 2 * x + np.random.randn(50))
ax.plot(x, np.sin(x) - 0.5 * x + np.random.randn(50))
ax.plot(x, np.sin(x) - 2 * x + np.random.randn(50))
ax.plot(x, np.sin(x) + np.random.randn(50))
ax.set_title("'fivethirtyeight' style sheet")
plt.show()
and rewrite it with MatChart:
from matchart import plot
import numpy as np
x = np.linspace(0, 10)
np.random.seed(19680801) # Fixing random state for reproducibility
plot([x, np.sin(x) + x + np.random.randn(50)],
[x, np.sin(x) + 0.5 * x + np.random.randn(50)],
[x, np.sin(x) + 2 * x + np.random.randn(50)],
[x, np.sin(x) - 0.5 * x + np.random.randn(50)],
[x, np.sin(x) - 2 * x + np.random.randn(50)],
[x, np.sin(x) + np.random.randn(50)],
title="'fivethirtyeight' style sheet",
theme='fivethirtyeight')
Note that default figure size differs.
Migrate from matplotlib stackplot
Let's take stackplots example:
import matplotlib.pyplot as plt
# data from United Nations World Population Prospects (Revision 2019)
# https://population.un.org/wpp/, license: CC BY 3.0 IGO
year = [1950, 1960, 1970, 1980, 1990, 2000, 2010, 2018]
population_by_continent = {
'africa' : [228, 284, 365, 477, 631, 814, 1044, 1275],
'americas': [340, 425, 519, 619, 727, 840, 943, 1006],
'asia' : [1394, 1686, 2120, 2625, 3202, 3714, 4169, 4560],
'europe' : [220, 253, 276, 295, 310, 303, 294, 293],
'oceania' : [12, 15, 19, 22, 26, 31, 36, 39],
}
fig, ax = plt.subplots()
ax.stackplot(year, population_by_continent.values(),
labels=population_by_continent.keys(), alpha=0.8)
ax.legend(loc='upper left')
ax.set_title('World population')
ax.set_xlabel('Year')
ax.set_ylabel('Number of people (millions)')
plt.show()
and rewrite it with MatChart:
from matchart import plot
# data from United Nations World Population Prospects (Revision 2019)
# https://population.un.org/wpp/, license: CC BY 3.0 IGO
year = [1950, 1960, 1970, 1980, 1990, 2000, 2010, 2018]
population_by_continent = {
'africa' : [228, 284, 365, 477, 631, 814, 1044, 1275],
'americas': [340, 425, 519, 619, 727, 840, 943, 1006],
'asia' : [1394, 1686, 2120, 2625, 3202, 3714, 4169, 4560],
'europe' : [220, 253, 276, 295, 310, 303, 294, 293],
'oceania' : [12, 15, 19, 22, 26, 31, 36, 39],
}
plot([year, population_by_continent.values()],
kind='stackplot',
labels=population_by_continent.keys(),
alpha=0.8,
legend=True,
legend_kwargs=dict(loc='upper left'),
limit=False,
title='World population',
xlabel='Year',
ylabel='Number of people (millions)')
Note that default figure size and theme differ.
Customization of plots
Let's take FiveThirtyEight style sheet example above and customize it before showing.
Imagine now we want to remove X and Y axes.
Straightforward solution (not bad)
To do the trick we can:
- only draw plot with
show=False
; - customize figure with matplotlib stuff;
- show plot with
matplotlib.pyplot.show()
.
from matchart import plot
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0, 10)
np.random.seed(19680801) # Fixing random state for reproducibility
fig, ax, arts = plot(
[x, np.sin(x) + x + np.random.randn(50)],
[x, np.sin(x) + 0.5 * x + np.random.randn(50)],
[x, np.sin(x) + 2 * x + np.random.randn(50)],
[x, np.sin(x) - 0.5 * x + np.random.randn(50)],
[x, np.sin(x) - 2 * x + np.random.randn(50)],
[x, np.sin(x) + np.random.randn(50)],
title="'fivethirtyeight' style sheet",
theme='fivethirtyeight',
show=False)
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
plt.show()
Clever solution (better)
To solve such kind of problems there is context manager support:
- draw plot with
context=True
; - customize figure with matplotlib stuff within context manager.
from matchart import plot
import numpy as np
x = np.linspace(0, 10)
np.random.seed(19680801) # Fixing random state for reproducibility
with plot(
[x, np.sin(x) + x + np.random.randn(50)],
[x, np.sin(x) + 0.5 * x + np.random.randn(50)],
[x, np.sin(x) + 2 * x + np.random.randn(50)],
[x, np.sin(x) - 0.5 * x + np.random.randn(50)],
[x, np.sin(x) - 2 * x + np.random.randn(50)],
[x, np.sin(x) + np.random.randn(50)],
title="'fivethirtyeight' style sheet",
theme='fivethirtyeight',
context=True) as results:
ax = results[1]
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
The best solution
Specially for lazy people there is special alias to be used within context manager:
- draw plot with
matchart.cplot()
; - customize figure with matplotlib stuff within context manager.
from matchart import cplot
import numpy as np
x = np.linspace(0, 10)
np.random.seed(19680801) # Fixing random state for reproducibility
with cplot(
[x, np.sin(x) + x + np.random.randn(50)],
[x, np.sin(x) + 0.5 * x + np.random.randn(50)],
[x, np.sin(x) + 2 * x + np.random.randn(50)],
[x, np.sin(x) - 0.5 * x + np.random.randn(50)],
[x, np.sin(x) - 2 * x + np.random.randn(50)],
[x, np.sin(x) + np.random.randn(50)],
title="'fivethirtyeight' style sheet",
theme='fivethirtyeight') as results:
ax = results[1]
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
Now you can customize plots just adding literally one letter.
Changelog
1.1.3:
- Add
context
parameter and aliasmatchart.cplot(...)
to delay plot showing within context manager. - Add
block
parameter of matplotlib's show function. - Small enhancements and bugs fixes.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.