Reputation: 10604
I'm an undergraduate studying computer science. For most of my classes, I have to make some sort of graph to display my results. Most of my professors want these graphs to be printed out (or, if they accept PDFs, they go on to print out a copy themselves) in order to grade it. I use matplotlib
in conjunction with a few other tools to generate the graphs, and that works well.
My issue, however, is that the (color) line graphs that I print out tend to be impossible to decipher. For a relatively mild example:
A worse example (and probably more of an issue with my design of the graph itself) would be:
When printed out in black and white, the series become impossible to distinguish.
An example of one of the scripts that I might use to generate a graph is below. I'd really like to find a way to make graphs that will look as clear as possible when printed out on a black and white printer --- how would I go about doing this? What techniques are most effective for increasing readability of charts and graphs in B/W?
from matplotlib import pyplot
SERIES_COLORS = 'bgrcmyk'
def plot_series(xy_pairs, series, color):
label_fmt = "{}Lock"
x, y_lists = zip(*xy_pairs)
normalized_ys = [[y / numpy.linalg.norm(ys) for y in ys]
for ys in y_lists]
y = [numpy.average(y_list) for i, y_list
in enumerate(normalized_ys)]
y_err = [numpy.std(y_list) for i, y_list in
enumerate(normalized_ys)]
pyplot.errorbar(x, y, y_err,
label=label_fmt.format(series),
fmt='{}o-'.format(color)
ls='-')
def main():
big_dataset = {
'a': data_for_a,
'b': data_for_b,
'c': data_for_c,.
....
}
for series, color in zip(SERIES_COLORS, big_dataset):
processed = do_work(big_dataset[series])
plot_series(processed, series, color)
pyplot.show()
Upvotes: 3
Views: 1709
Reputation: 2190
You can play with different line styles and markers.
This is a nice example taken from http://matplotlib.org/examples/pylab_examples/line_styles.html
#!/usr/bin/env python
# This should probably be replaced with a demo that shows all
# line and marker types in a single panel, with labels.
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
import numpy as np
t = np.arange(0.0, 1.0, 0.1)
s = np.sin(2*np.pi*t)
linestyles = ['_', '-', '--', ':']
markers = []
for m in Line2D.markers:
try:
if len(m) == 1 and m != ' ':
markers.append(m)
except TypeError:
pass
styles = markers + [
r'$\lambda$',
r'$\bowtie$',
r'$\circlearrowleft$',
r'$\clubsuit$',
r'$\checkmark$']
colors = ('b', 'g', 'r', 'c', 'm', 'y', 'k')
plt.figure(figsize=(8,8))
axisNum = 0
for row in range(6):
for col in range(5):
axisNum += 1
ax = plt.subplot(6, 5, axisNum)
color = colors[axisNum % len(colors)]
if axisNum < len(linestyles):
plt.plot(t, s, linestyles[axisNum], color=color, markersize=10)
else:
style = styles[(axisNum - len(linestyles)) % len(styles)]
plt.plot(t, s, linestyle='None', marker=style, color=color, markersize=10)
ax.set_yticklabels([])
ax.set_xticklabels([])
plt.show()
You can also combine them all together.
x = linspace(0,1,10)
ls = ["-","--","-."]
markers = ["o","s","d"]
clrs = ["k"]
k = 1
for l in ls:
for m in markers:
for c in clrs:
plot(x,x**k,m+l+c)
k+=1
Hope it helps.
Upvotes: 3