Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib plot with variable line width

Is it possible to plot a line with variable line width in matplotlib? For example:

from pylab import *
x = [1, 2, 3, 4, 5]
y = [1, 2, 2, 0, 0]
width = [.5, 1, 1.5, .75, .75]

plot(x, y, linewidth=width)

This doesn't work because linewidth expects a scalar.

Note: I'm aware of *fill_between()* and *fill_betweenx()*. Because these only fill in x or y direction, these do not do justice to cases where you have a slanted line. It is desirable for the fill to always be normal to the line. That is why a variable width line is sought.

like image 841
Hamid Avatar asked Oct 15 '13 20:10

Hamid


People also ask

How do I change the width of a line in Matplotlib?

Matplotlib allows you to adjust the line width of a graph plot using the linewidth attribute. If you want to make the line width of a graph plot thinner, then you can make linewidth less than 1, such as 0.5 or 0.25.

Which attribute of plot function is used to set the width of line in line plot?

The linewidth and linestyle property can be used to change the width and the style of the line chart. Linewidth is specified in pixels.

What is %Matplotlib inline?

You can use the magic function %matplotlib inline to enable the inline plotting, where the plots/graphs will be displayed just below the cell where your plotting commands are written. It provides interactivity with the backend in the frontends like the jupyter notebook.

How do I increase linewidth in Matlab?

set(graph1,'LineWidth',2);


2 Answers

Use LineCollections. A way to do it along the lines of this Matplotlib example is

import numpy as np from matplotlib.collections import LineCollection import matplotlib.pyplot as plt x = np.linspace(0,4*np.pi,10000) y = np.cos(x) lwidths=1+x[:-1] points = np.array([x, y]).T.reshape(-1, 1, 2) segments = np.concatenate([points[:-1], points[1:]], axis=1) lc = LineCollection(segments, linewidths=lwidths,color='blue') fig,a = plt.subplots() a.add_collection(lc) a.set_xlim(0,4*np.pi) a.set_ylim(-1.1,1.1) fig.show() 

output

like image 144
gg349 Avatar answered Oct 06 '22 21:10

gg349


An alternative to Giulio Ghirardo's answer which divides the lines in segments you can use matplotlib's in-built scatter function which construct the line by using circles instead:

from matplotlib import pyplot as plt import numpy as np  x = np.linspace(0,10,10000) y = 2 - 0.5*np.abs(x-4) lwidths = (1+x)**2 # scatter 'o' marker size is specified by area not radius  plt.scatter(x,y, s=lwidths, color='blue') plt.xlim(0,9) plt.ylim(0,2.1) plt.show() 

In my experience I have found two problems with dividing the line into segments:

  1. For some reason the segments are always divided by very thin white lines. The colors of these lines get blended with the colors of the segments when using a very large amount of segments. Because of this the color of the line is not the same as the intended one.

  2. It doesn't handle very well very sharp discontinuities.

like image 29
J.Bet Avatar answered Oct 06 '22 21:10

J.Bet