How to draw a line inside a scatter plot

I can’t believe it’s so complicated, but I’ve tried and searched Google for some time.

I just want to analyze my scatter plot with a few graphical functions. First, I want to add just a string.

So, I have several (4) points, and I want to add a line to it, as in this plot (source: http://en.wikipedia.org/wiki/File:ROC_space-2.png )

enter image description here

Now it will not work. And, frankly, building documentation-examples-gallery and matplotlib content is a poor source of information.

My code is based on a simple scatter chart from the gallery:

# definitions for the axes left, width = 0.1, 0.85 #0.65 bottom, height = 0.1, 0.85 #0.65 bottom_h = left_h = left+width+0.02 rect_scatter = [left, bottom, width, height] # start with a rectangular Figure fig = plt.figure(1, figsize=(8,8)) axScatter = plt.axes(rect_scatter) # the scatter plot: p1 = axScatter.scatter(x[0], y[0], c='blue', s = 70) p2 = axScatter.scatter(x[1], y[1], c='green', s = 70) p3 = axScatter.scatter(x[2], y[2], c='red', s = 70) p4 = axScatter.scatter(x[3], y[3], c='yellow', s = 70) p5 = axScatter.plot([1,2,3], "r--") plt.legend([p1, p2, p3, p4, p5], [names[0], names[1], names[2], names[3], "Random guess"], loc = 2) # now determine nice limits by hand: binwidth = 0.25 xymax = np.max( [np.max(np.fabs(x)), np.max(np.fabs(y))] ) lim = ( int(xymax/binwidth) + 1) * binwidth axScatter.set_xlim( (-lim, lim) ) axScatter.set_ylim( (-lim, lim) ) xText = axScatter.set_xlabel('FPR / Specificity') yText = axScatter.set_ylabel('TPR / Sensitivity') bins = np.arange(-lim, lim + binwidth, binwidth) plt.show() 

Everything works except p5, which is a string.

Now how should this work? What is good practice here?

+4
source share
2 answers

plot takes y values ​​and uses x as an index array 0..N-1 or x and y values, as described in the documentation. So you can use

 p5 = axScatter.plot((0, 1), "r--") 

in your code to build a line.

However, you are asking for "good practice." The following code (hopefully) shows some “good practice” and some matplotlib features to create the plot you mentioned in your question.

 import numpy as np import matplotlib.pyplot as plt # create some data xy = np.random.rand(4, 2) xy_line = (0, 1) # set up figure and ax fig, ax = plt.subplots(figsize=(8,8)) # create the scatter plots ax.scatter(xy[:, 0], xy[:, 1], c='blue') for point, name in zip(xy, 'ABCD'): ax.annotate(name, xy=point, xytext=(0, -10), textcoords='offset points', color='blue', ha='center', va='center') ax.scatter([0], [1], c='black', s=60) ax.annotate('Perfect Classification', xy=(0, 1), xytext=(0.1, 0.9), arrowprops=dict(arrowstyle='->')) # create the line ax.plot(xy_line, 'r--', label='Random guess') ax.annotate('Better', xy=(0.3, 0.3), xytext=(0.2, 0.4), arrowprops=dict(arrowstyle='<-'), ha='center', va='center') ax.annotate('Worse', xy=(0.3, 0.3), xytext=(0.4, 0.2), arrowprops=dict(arrowstyle='<-'), ha='center', va='center') # add labels, legend and make it nicer ax.set_xlabel('FPR or (1 - specificity)') ax.set_ylabel('TPR or sensitivity') ax.set_title('ROC Space') ax.set_xlim(0, 1) ax.set_ylim(0, 1) ax.legend() plt.tight_layout() plt.savefig('scatter_line.png', dpi=80) 

scatter_with_line.png

By the way, I think the matplotlibs documentation is very useful today.
+11
source

line p5 should be:

 p5 = axScatter.plot([1,2,3],[1,2,3], "r--") 

argument 1 is a list of x values, and argument 2 is a list of y values

If you just need a straight line, you only need to specify values ​​for the ends of the line.

+1
source

Source: https://habr.com/ru/post/1440871/


All Articles