Reputation: 6331
I have a specific implementation question about taking data mapped out using a colormapping (cmap) and converting it to rgba values. Essentially, I have a bunch of data which I would like to create an errorbar() plot for where the points as well as the errorbars themselves are colored by the size of some other value (for concreteness let's say it's contribution to the chi-square of the fit of some model). Let's say I have an (N,4) array called D, where the first two columns are the X and Y data, the third column is the value of the errorbar, and the last column is its contribution to the chi-square function.
How would I go about first 1) mapping the range of chi-square contribution values to a cmap, and secondly, 2) how can I get rgba values from these in order to loop over the errorbar() function to plot what I was hoping to plot?
This may actually be helpful (http://matplotlib.org/api/cm_api.html), but I'm unable to find any examples or additional information about how to use ScalarMappable() (which does have a to_rgba() method).
Thanks!
Upvotes: 3
Views: 5988
Reputation: 49002
You can map scalar values to a colormap by calling the objects in matplotlib.cm
on the values. The values should lie between 0 and 1. So, to get RBGA values for some chi-square distributed data (which I'll generate randomly), I would do:
chisq = np.random.chisquare(4, 8)
chisq -= chisq.min()
chisq /= chisq.max()
errorbar_colors = cm.winter(chisq)
Instead of having the color scale start and end at the minimum and maximum actual values, you could subtract off the minimum and divide by the maximum you want.
Now errorbar_colors
will be a (8, 4)
array of RGBA values from the winter
colormap:
array([[ 0. , 0.7372549 , 0.63137255, 1. ],
[ 0. , 0.7372549 , 0.63137255, 1. ],
[ 0. , 0.4745098 , 0.7627451 , 1. ],
[ 0. , 1. , 0.5 , 1. ],
[ 0. , 0.36078431, 0.81960784, 1. ],
[ 0. , 0.47843137, 0.76078431, 1. ],
[ 0. , 0. , 1. , 1. ],
[ 0. , 0.48627451, 0.75686275, 1. ]])
To plot this, you can just iterate over the colors and the datapoints and draw errorbars:
heights = np.random.randn(8)
sem = .4
for i, (height, color) in enumerate(zip(heights, errorbar_colors)):
plt.plot([i, i], [height - sem, height + sem], c=color, lw=3)
plt.plot(heights, marker="o", ms=12, color=".3")
However, none of the built-in matplotlib colormaps are all that well-suited to this task. For some improvement, you could use seaborn to generate a sequential color palette that can be used to color lines:
import numpy as np
import seaborn
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
chisq = np.random.chisquare(4, 8)
chisq -= chisq.min()
chisq /= chisq.max()
cmap = ListedColormap(seaborn.color_palette("GnBu_d"))
errorbar_colors = cmap(chisq)
heights = np.random.randn(8)
sem = .4
for i, (height, color) in enumerate(zip(heights, errorbar_colors)):
plt.plot([i, i], [height - sem, height + sem], c=color, lw=3)
plt.plot(heights, marker="o", ms=12, color=".3")
But even here, I have doubts that this is going to be the best way to get your point across. I don't know exactly what your data look like, but I would advise making two plots, one with the dependent variable you would be plotting here, and a second with the chi square statistic as the dependent variable. Alternatively, if you're interested in the relationship between the size of the error bars and the chi square value, I would plot that directly with a scatterplot.
Upvotes: 4