If we have two vector data such as polygons or polylines (shown in graph below). How can we get find the overlap and create a new x,y vector data for this new shape? (or simply get the area of the new shape.
import numpy as np
import matplotlib.pyplot as plt
x1 = [10, 20, 40, 50, 50, 40, 20, 10, 10];
y1 = [20, 10, 10, 20, 40, 50, 50, 40, 20];
x2 = [30, 60, 30, 0, 30];
y2 = [40, 50, 70, 60, 40];
fig, ax = plt.subplots()
ax.plot(x1, y1)
ax.plot(x2, y2)
plt.show()
For example, for the above graph where the intersections are, can we get the x,y coordinates/data for this new shape created from the overlap? or get the area of it instead?
Constructing the intersection of two polygons is uneasy in the general case. https://en.wikipedia.org/wiki/Vatti_clipping_algorithm
When the polygons are convex, as in your example, you can use the Sutherland-Hodgman algorithm. https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm
Related
I am hoping to graph data that looks something like:
import matplotlib.pyplot as plt
x = [0, 350, 40, 55, 60]
y = [0, 20, 40, 10, 20]
plt.scatter(x,y);
Gives something like this:
However I would like to change this so the axes run from 180 to 360 and then from 0 to 180 all in the same figure. Essentially I want connect 360 to 0 in the center of the figure.
There might be something creative you can do with matplotlib.units, but I often find that interface to be quite clunky.
I'm not 100% certain the result you want, but from your description it sounds like you want a plot in cartesian coordinates with an xaxis that goes from 180 → 360 → 180. Unfortunately this is not directly doable with a single Axes in matplotlib (without playing around with the units above).
Thankfully, you can stitch together 2 plots to get the desired end result that you want:
import matplotlib.pyplot as plt
x = [0, 350, 40, 55, 60]
y = [0, 20, 40, 10, 20]
fig, (ax1, ax2) = plt.subplots(1, 2, sharey=True, grid
spec_kw={"wspace": 0})
ax1.scatter(x, y, clip_on=False)
ax2.scatter(x, y, clip_on=False)
ax1.set_xlim(180, 360)
ax1.set_xticks([180, 240, 300, 360])
ax1.spines["right"].set_visible(False)
ax2.set_xlim(0, 180)
ax2.set_xticks([60, 120, 180])
ax2.yaxis.set_visible(False)
ax2.spines["left"].set_visible(False)
plt.show()
The trick for the above is that I actually plotted all of the data twice (.scatter(...)), laid those plots out next to eachother ({'wspace': 0}) and then limited their data view (.set_xlim) to make it appear as a seamless plot that goes from 180 → 360 → 180.
You may also be asking for a plot not in cartesian coordinates, but in polar coordinates. In that case you can use the following code:
import matplotlib.pyplot as plt
from numpy import deg2rad
x = [0, 350, 40, 55, 60]
y = [0, 20, 40, 10, 20]
fig, ax = plt.subplots(subplot_kw={"projection": "pola
r"})
ax.scatter(deg2rad(x), y)
ax.set_yticks([0, 20, 40, 60])
plt.show()
Most people would plot that as -180 to 180?
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(2, 1)
x = np.arange(0, 360, 10)
y = x * 1
y[x>180] = y[x>180] - 360
ax[0].scatter(x, np.abs(y), c=x)
ax[1].scatter(y, np.abs(y), c=x)
plt.show()
I have the following lists that correspond to 6 (clients) points (each one having an id, and x and y coordinates)
allIds = [0, 1, 2, 3, 4, 5],
allxs = [50, 25, 43, 80, 25, 18]
allys = [50, 54, 96, 50, 90, 47]
For example, the 1st point has an id of 0, its x coordinates are 50, and its y coordinates are 50, and so on.
I am trying to solve a traveling salesman problem, so I want to plot the points of a specific route between points, connected with a line that will represent the closed route.
The final route I want to plot is represented by the following list:
final_route = [0, 4, 5, 2, 1, 3, 0]
and represents a path between clients' ids
So far i have only managed to plot the points only, with the following code:
fig, ax = plt.subplots()
fig.set_size_inches(6, 6)
ax.plot(all_x, all_y, ls="", marker="o", markersize=8)
for xi, yi, pidi in zip(all_x, all_y, all_ids):
ax.annotate(str(pidi), xy=(xi,yi))
plt.xlim([0, 100])
plt.ylim([0, 100])
plt.show()
Which produces the following plot:
Plot of poits
Any ideas about how to plot the line between the points? Thanks
I'm new to python and I am trying to make re-arrange the rectangle from raw data. I'm using bin packing algorithmn and I want to sort it with color like below. Please need help?
Output Now:
Expected Output:
There are small changes in the code please follow below code once:
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
fig = plt.figure()
ax = fig.add_subplot(111)
temp_y=0
i=0
layout_height = 300
layout_width = 300
ax.set_xlim([0, layout_height])
ax.set_ylim([0, layout_width])
area_height = [80, 75, 50, 60, 52, 72, 100, 120, 150]
area_width = [50, 46, 52, 52, 50, 48, 25, 40, 48]
for (i,j) in zip(area_height, area_width):
print(i,j)
ax.add_patch(Rectangle((0, temp_y), float(j), float(i),edgecolor ='black',facecolor = 'red'))
temp_y = temp_y + float(i)
I'm trying to use seaborn to create a colored bubbleplot of 3-D points (x,y,z), each coordinate being an integer in range [0,255]. I want the axes to represent x and y, and the hue color and size of the scatter bubbles to represent the z-coordinate.
The code:
import seaborn
seaborn.set()
import pandas
import matplotlib.pyplot
x = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200]
y = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200]
z = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200]
df = pandas.DataFrame(list(zip(x, y, z)), columns =['x', 'y', 'z'])
ax = seaborn.scatterplot(x="x", y="y",
hue="z",
data=df)
matplotlib.pyplot.xlim(0,255)
matplotlib.pyplot.ylim(0,255)
matplotlib.pyplot.show()
gets me pretty much what I want:
This however makes the hue range be based on the data in z. I instead want to set the range according to the range of the min and max z values (as 0,255), and then let the color of the actual points map onto that range accordingly (so if a point has z-value 50, then that should be mapped onto the color represented by the value 50 in the range [0,255]).
My summarized question:
How to manually set the hue color range of a numerical variable in a scatterplot using seaborn?
I've looked thoroughly online on many tutorials and forums, but have not found an answer. I'm not sure I've used the right terminology. I hope my message got across.
Following #JohanC's suggestion of using hue_norm was the solution. I first tried doing so by removing the [hue=] parameter and only using the [hue_norm=] parameter, which didn't produce any colors at all (which makes sense).
Naturally one should use both the [hue=] and the [hue_norm=] parameters.
import seaborn
seaborn.set()
import pandas
import matplotlib.pyplot
x = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200]
y = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200]
z = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 255]
df = pandas.DataFrame(list(zip(x, y, z, my_sizes)), columns =['x', 'y', 'z'])
ax = seaborn.scatterplot(x="x", y="y",
hue="z",
hue_norm=(0,255), # <------- the solution
data=df)
matplotlib.pyplot.xlim(0,255)
matplotlib.pyplot.ylim(0,255)
matplotlib.pyplot.show()
I'm plotting a graph on a x axis (solution concentration) against efficiency (y). I have this set up to display for x between 0 to 100, but I want to add another datapoint as a control, without any solution at all. I'm having issues as this doesn't really fit anywhere on the concentration axis, but Id like to add it either before 0 or after 100, potentially with a break in the axis to separate them. So my x-axis would look like ['control', 0, 20, 40, 60, 80, 100]
MWE:
x_array = ['control', 0, 20, 40, 50, 100]
y_array = [1, 2, 3, 4, 5, 6]
plt.plot(x_array, y_array)
Trying this, I get an error of:
ValueError: could not convert string to float: 'control'
Any ideas how i could make something like this work? Ive looked at xticks but that would plot the x axis as strings, therefore losing the continuity of the axis, which would mess up the plot as the datapoints are not spaced equidistant.
You can add a single point to your graph as a separate call to plot, then adjust the x-axis labels.
import matplotlib.pyplot as plt
x_array = [0, 20, 40, 50, 100]
y_array = [2, 3, 4, 5, 6]
x_con = -20
y_con = 1
x_ticks = [-20, 0, 20, 40, 60, 80, 100]
x_labels = ['control', 0, 20, 40, 60, 80, 100]
fig, ax = plt.subplots(1,1)
ax.plot(x_array, y_array)
ax.plot(x_con, y_con, 'ro') # add a single red dot
# set tick positions, adjust label text
ax.xaxis.set_ticks(x_ticks)
ax.xaxis.set_ticklabels(x_labels)
ax.set_xlim(x_con-10, max(x_array)+3)
ax.set_ylim(0,7)
plt.show()