I have two lists, dates and values. I want to plot them using matplotlib. The following creates a scatter plot of my data.
import matplotlib.pyplot as plt
plt.scatter(dates,values)
plt.show()
plt.plot(dates, values) creates a line graph.
But what I really want is a scatterplot where the points are connected by a line.
Similar to in R:
plot(dates, values)
lines(dates, value, type="l")
, which gives me a scatterplot of points overlaid with a line connecting the points.
How do I do this in python?
I think #Evert has the right answer:
plt.scatter(dates,values)
plt.plot(dates, values)
plt.show()
Which is pretty much the same as
plt.plot(dates, values, '-o')
plt.show()
You can replace -o with another suitable format string as described in the documentation.
You can also split the choices of line and marker styles using the linestyle= and marker= keyword arguments.
For red lines an points
plt.plot(dates, values, '.r-')
or for x markers and blue lines
plt.plot(dates, values, 'xb-')
In addition to what provided in the other answers, the keyword "zorder" allows one to decide the order in which different objects are plotted vertically.
E.g.:
plt.plot(x,y,zorder=1)
plt.scatter(x,y,zorder=2)
plots the scatter symbols on top of the line, while
plt.plot(x,y,zorder=2)
plt.scatter(x,y,zorder=1)
plots the line over the scatter symbols.
See, e.g., the zorder demo
They keyword argument for this is marker, and you can set the size of the marker with markersize. To generate a line with scatter symbols on top:
plt.plot(x, y, marker = '.', markersize = 10)
To plot a filled spot, you can use marker '.' or 'o' (the lower case letter oh). For a list of all markers, see:
https://matplotlib.org/stable/api/markers_api.html
Related
Here is the instruction:
a string "fig_type", which is one of the two values: "single" or "subplots".
The input argument "fig_type" determines how to draw the plots:
if "fig_type" is "single", you should produce one set of axes, draw all the plots together in the same axes, and differentiate them e.g. by line or marker colour or style.
if "fig_type" is "subplots", you should produce 𝑟
r
different sets of axes (in the same figure), so that each plot is drawn in a different subplot. Choose how to set up your subplots so that all plots are sufficiently large and readable.
Then I write a code like that, I'm not quite sure if that's how it should be written, and I'm not sure what single means in this context.
if fig_type =='single':
fig, ax = plt.plot()
else:
fig, ax = plt.subplots()
I was trying to plot a vertical line with markers on it using ax.axvline but the markers only show up on the bottom and top of the figure. I have played around with the markevery kwarg but it does not seem to have any effect when I change it even though it works for a normal line plot. Does anyone know if this is because no discrete values are specified along the axis or am I just doing something wrong?
I realize that I can plot a vertical line on my own and specify the markers, but I figure given the purpose of axvline I should use it.
Here is an example code of what I am talking about:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-10,10)
y = x**2-15.
fig = plt.figure(figsize=(4,4))
ax = plt.subplot(111)
ax.plot(y,x) #Test curve
ax.plot(2+np.zeros(len(x)),x,marker='X',markevery=1) #another way to plot what I want.
ax.axvline(0,c='r',marker='X',markevery=1) #markerevery doesn't seem to work
plt.show()
As mentioned by ImportanceofBeingErnest, the markereverykwarg does not apply for axvline or axhline because there are technically only 2 points used to draw the line at the boundaries.
In this example of a marker from my scatter plot I have set the color to green, and edge color to black, and hatch to "|". For the hatch pattern to show up at all I must set the edgecolor, however when I do, I get a very thick border around the marker. Two questions:
1) How can I to set the size of this border (preferably to 0)?
2) How can I increase the thickness of the hatch lines?
You just need to set the linewidth to control the marker border thickness.
You can increase the density of hatching, by repeating symbols (in the example below, the '|' is repeated in the R/H pane; note that to obtain NW->SE diagonal lines the symbol must be escaped so needs twice as many characters to really double it -- '\\\\' is density 2 while '||||' is density 4). However, I don't think the thickness of individual lines within hatching is controllable.
See the code example below to produce scatter plots such as these:
import matplotlib.pyplot as plt
# generate some data
x = [1,2,3,4,5,8]
y= [i**2 for i in x]
y2= [60-i**2+3*i for i in x]
# plot markers with thick borders
plt.subplot(121)
plt.scatter(x,y, s=500, marker='s', edgecolor='black', linewidth=3, facecolor='green', hatch='|')
# compare with no borders, and denser hatch.
plt.subplot(122)
plt.scatter(x,y2, s=500, marker='s', edgecolor='black', linewidth=0, facecolor='green', hatch='||||')
plt.show()
matplotlib documentation on collections
and scatter.
This is several years after you asked the question, but the only way I've found to do it is to change the matplotlib.rc.
You can do this either in the actual .rc file or within your python script, e.g.
import matplotlib as mpl
mpl.rc('hatch', color='k', linewidth=1.5)
This will make all of the hatch lines in your script black and thickness 1.5 rather than the default 1.0.
If you're using plt.plot, you'll want to pass argument markeredgewidth.
I'm using the matplotlib library in python to generate publication-quality xy scatter plots. I ran into a problem regarding the markers in the legend. I'm plotting 2 different xy-scatter series; one is a set of xy points that forms a curve, and the other is a single xy point.
I would like the legend to show 3 markers for the "curve", and 1 marker for the single point. The only way I know how to change the number of legend markers is using the "scatterpoints" argument when declaring the legend. However, this argument sets the number of markers for all series in the legend, and I'm not sure how to change each legend entry individually.
Sadly I can't post pictures as a new user, but hopefully this description is sufficient. Is there a way to set scatterpoints values individually for each legend entry using matplotlib?
EDIT: Here are links showing images with different values for scatterpoints.
scatterpoints = 3: http://imgur.com/8ONAT
scatterpoints = 1: http://imgur.com/TFcYV
Hopefully this makes the issue a bit more clear.
you can get the line in legend, and change it yourself:
import numpy as np
import pylab as pl
x = np.linspace(0, 2*np.pi, 100)
pl.plot(x, np.sin(x), "-x", label=u"sin")
pl.plot(x, np.random.standard_normal(len(x)), 'o', label=u"rand")
leg = pl.legend(numpoints=3)
l = leg.legendHandles[1]
l._legmarker.set_xdata(l._legmarker.get_xdata()[1:2])
l._legmarker.set_ydata(l._legmarker.get_ydata()[1:2])
##or
#l._legmarker.set_markevery(3)
pl.show()
Legend.legendHandles is a list of all the lines in legend, and the _legmarker attribute of the line is the marks.
You can call set_markevery(3) or set_xdata() & set_ydata() to change the number of marks.
I am using matplotlib in Python to plot a line with errorbars as follows:
plt.errorbar(xvalues, up_densities, yerr=ctl_sds, fmt='-^', lw=1.2, markersize=markersize,
markeredgecolor=up_color, color=up_color, label="My label", clip_on=False)
plt.xticks(xvalues)
I set the ticks on the x-axis using "xticks". However, the error bars of the last point in xvalues (i.e. xvalues[-1]) are clipped on the right -- meaning only half an error bar appears. This is true even with the clip_on=False option. How can I fix this, so that the error bars appear in full, even though their right side is technically outside xvalues[-1]?
thanks.
In matplotlib, most of the detailed control needs to be done through the Artists. I think this should do what you want:
import matplotlib.pyplot as plt
from random import uniform as r
x = range(10)
e = plt.errorbar(x, [r(2,10) for i in x], [r(.1,1) for i in x], capsize=8, color='r')
for b in e[1]:
b.set_clip_on(False)
plt.show()
The problem you were having is that the clip_on keyword was being used to control the markers and not the error bars. To control the errorbars, plt.errorbar returns a tuple, where the second item is a list of errorbars. So here I go through the list and turn the clipping off for each errorbar.
Is this what you mean? Do you want to redefine the horizontal limits of your plot?
plt.errorbar(range(5), [3,2,4,5,1], yerr=[0.1,0.2,0.3,0.4,0.5])
ax = plt.gca()
ax.set_xlim([-0.5,4.5])
(source: stevetjoa.com)