1

So I've been going round in circles on this for the last day, and hoping someone can put me out of my misery.

I have a function f that depends on x and y values and when plotting f against y, gives the following figure.

Now each of the lines are for a value of x [0,1] and I feel there must be a way to colour/contour the plot such that it can easily be identified which line corresponds to what value of x. I've tried numerous searches, but have not found anything that helps in this instance.

The code to reproduce the data that gives my figure is as below. Any help would be great, as I feel I'm missing something glaringly obvious here.

import numpy as np
import matplotlib.pyplot as plt

y = np.linspace(0,100)
x = np.linspace(0,1,11)

f = np.zeros(( len(y), len(x) ))


for j in range(len(x)):
    i=0
    for r in y:
        f[i,j] = (1000 + (-r * 2)) + (1000*(1-x[j]))
        i += 1

 plt.plot(f, y)
Matthew
  • 33
  • 1
  • 5
  • 1
    What about a [legend](http://matplotlib.org/users/legend_guide.html)? – MKesper Feb 16 '17 at 12:11
  • http://stackoverflow.com/questions/16992038/inline-labels-in-matplotlib and http://matplotlib.org/users/legend_guide.html – Dadep Feb 16 '17 at 12:16
  • Or plotting in [3D](http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html), or [annotations](http://matplotlib.org/users/annotations_intro.html), or [colormapping the lines](http://stackoverflow.com/questions/8945699/gnuplot-linecolor-variable-in-matplotlib/18516488#18516488), or if you have only a very limited number of x values use a different [linestyle](http://matplotlib.org/api/lines_api.html#matplotlib.lines.Line2D.set_linestyle) for each. – armatita Feb 16 '17 at 12:17

3 Answers3

0
import numpy as np
import matplotlib.pyplot as plt

y = np.linspace(0, 100)
x = np.linspace(0, 1, 11)
f = np.zeros((len(y), len(x)))

for j in range(len(x)):
    i = 0
    for r in y:
        f[i, j] = (1000 + (-r * 2)) + (1000 * (1 - x[j]))
        i += 1

plt.plot(f, y)
labels = [f[xs, 0] for xs in x]
plt.legend(labels, loc='best')
plt.show()

Just fix the labels

Jadim
  • 182
  • 2
  • 12
aslavkin
  • 214
  • 1
  • 7
  • Sorry I probably should have mentioned in the original post that I didn't want to use a legend, as I have another similar function that would be plotted together and the legend gets out of hand quickly. Thanks for the response though. – Matthew Feb 16 '17 at 15:03
0

I gave a few possibilities in my comment:

Or plotting in 3D, or annotations, or colormapping the lines, or if you have only a very limited number of x values use a different linestyle for each.

Beside that you can create a new axis specifically for x. In the following snippet adapted from your code I put the x value in the top horizontal axis:

import numpy as np
import matplotlib.pyplot as plt

y = np.linspace(0,100)
x = np.linspace(0,1,11)

f = np.zeros(( len(y), len(x) ))


for j in range(len(x)):
    i=0
    for r in y:
        f[i,j] = (1000 + (-r * 2)) + (1000*(1-x[j]))
        i += 1

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()
ax2.set_xticks(x)
ax2.set_xticklabels(["%.3f" % xi for xi in x])
ax1.plot(f, y)

The result is the following:

Double x axis

Community
  • 1
  • 1
armatita
  • 12,825
  • 8
  • 48
  • 49
0

Since the lines correspond to more or less continuous values of x, I would color the lines according to a colormap. Then use a colorbar to show the mapping of x to colors.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cmx
import matplotlib.colors as colors

y = np.linspace(0,100)
x = np.linspace(0,1,11)

f = np.zeros(( len(y), len(x) ))


for j in range(len(x)):
    i=0
    for r in y:
        f[i,j] = (1000 + (-r * 2)) + (1000*(1-x[j]))
        i += 1


cn  = colors.Normalize(vmin=0, vmax=1)
scalar_map = cmx.ScalarMappable(norm=cn, cmap='jet')
# see plt.colormaps() for many more colormaps

for f_, x_ in zip(f.T, x):
    c = scalar_map.to_rgba(x_)
    plt.plot(f_, y, color=c)

scalar_map.set_array([])  # dunno why we need this. plt.colorbar fails otherwise.
plt.colorbar(scalar_map, label='x')

enter image description here

MB-F
  • 22,770
  • 4
  • 61
  • 116