Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
352 views
in Technique[技术] by (71.8m points)

color mapping - matplotlib - black & white colormap (with dashes, dots etc)

I am using matplotlib to create 2d line-plots. For the purposes of publication, I would like to have those plots in black and white (not grayscale), and I am struggling to find a non-intrusive solution for that.

Gnuplot automatically alters dashing patterns for different lines, is something similar possible with matplotlib?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Below I provide functions to convert a colored line to a black line with unique style. My quick test showed that after 7 lines, the colors repeated. If this is not the case (and I made a mistake), then a minor adjustment is needed for the "constant" COLORMAP in the provided routine.

Here's the routine and example:

import matplotlib.pyplot as plt
import numpy as np

def setAxLinesBW(ax):
    """
    Take each Line2D in the axes, ax, and convert the line style to be 
    suitable for black and white viewing.
    """
    MARKERSIZE = 3

    COLORMAP = {
        'b': {'marker': None, 'dash': (None,None)},
        'g': {'marker': None, 'dash': [5,5]},
        'r': {'marker': None, 'dash': [5,3,1,3]},
        'c': {'marker': None, 'dash': [1,3]},
        'm': {'marker': None, 'dash': [5,2,5,2,5,10]},
        'y': {'marker': None, 'dash': [5,3,1,2,1,10]},
        'k': {'marker': 'o', 'dash': (None,None)} #[1,2,1,10]}
        }


    lines_to_adjust = ax.get_lines()
    try:
        lines_to_adjust += ax.get_legend().get_lines()
    except AttributeError:
        pass

    for line in lines_to_adjust:
        origColor = line.get_color()
        line.set_color('black')
        line.set_dashes(COLORMAP[origColor]['dash'])
        line.set_marker(COLORMAP[origColor]['marker'])
        line.set_markersize(MARKERSIZE)

def setFigLinesBW(fig):
    """
    Take each axes in the figure, and for each line in the axes, make the
    line viewable in black and white.
    """
    for ax in fig.get_axes():
        setAxLinesBW(ax)

xval = np.arange(100)*.01

fig = plt.figure()
ax = fig.add_subplot(211)

ax.plot(xval,np.cos(2*np.pi*xval))
ax.plot(xval,np.cos(3*np.pi*xval))
ax.plot(xval,np.cos(4*np.pi*xval))
ax.plot(xval,np.cos(5*np.pi*xval))
ax.plot(xval,np.cos(6*np.pi*xval))
ax.plot(xval,np.cos(7*np.pi*xval))
ax.plot(xval,np.cos(8*np.pi*xval))

ax = fig.add_subplot(212)
ax.plot(xval,np.cos(2*np.pi*xval))
ax.plot(xval,np.cos(3*np.pi*xval))
ax.plot(xval,np.cos(4*np.pi*xval))
ax.plot(xval,np.cos(5*np.pi*xval))
ax.plot(xval,np.cos(6*np.pi*xval))
ax.plot(xval,np.cos(7*np.pi*xval))
ax.plot(xval,np.cos(8*np.pi*xval))

fig.savefig("colorDemo.png")
setFigLinesBW(fig)
fig.savefig("bwDemo.png")

This provides the following two plots: First in color: enter image description here Then in black and white: enter image description here

You can adjust how each color is converted to a style. If you just want to only play with the dash style (-. vs. -- vs. whatever pattern you want), set the COLORMAP corresponding 'marker' value to None and adjusted the 'dash' pattern, or vice versa.

For example, the last color in the dictionary is 'k' (for black); originally I had only a dashed pattern [1,2,1,10], corresponding to one pixel shown, two not, one shown, 10 not, which is a dot-dot-space pattern. Then I commented that out, setting the dash to (None,None), a very formal way of saying solid line, and added the marker 'o', for circle.

I also set a 'constant' MARKERSIZE, which will set the size of each marker, because I found the default size to be a little large.

This obviously does not handle the case when your lines already have a dash or marker patter, but you can use these routines as a starting point to build a more sophisticated converter. For example if you original plot had a red solid line and a red dotted line, they both would turn into black dash-dot lines with these routines. Something to keep in mind when you use them.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...