Connecting points in ggplot2 graph with lines
From @Duck's comment: just add + geom_line()
or + geom_path()
to a plot. ("Which to use" depends on your use: geom_line
connects by the order on the x-axis, geom_path
connects in the order they appear in the data, both have valid uses. In this case they appear to be the same, but keep this in mind if your real data changes.)
ggplot(popdata, aes(predator, prey, color = k)) +
geom_point() +
geom_line()
(Similarly for the other plots.)
I should note that order matters.
# left
ggplot(popdata, aes(predator, prey, color = k)) +
geom_point() +
geom_line(color="black")
# right
ggplot(popdata, aes(predator, prey, color = k)) +
geom_line(color="black") +
geom_point()
Algorithm for connecting points in a graph with curved lines
I think any Piecewise curve interpolation should do it. Here small C++ example:
//---------------------------------------------------------------------------
const int n=7; // points
const int n2=n+n;
float pnt[n2]= // points x,y ...
{
1.0, 220.0,
2.0, 40.0,
3.0,-130.0,
4.0,-170.0,
5.0,- 40.0,
6.0, 90.0,
7.0, 110.0,
};
//---------------------------------------------------------------------------
void getpnt(float *p,float t) // t = <0,n-1>
{
int i,ii;
float *p0,*p1,*p2,*p3,a0,a1,a2,a3,d1,d2,tt,ttt;
// handle t out of range
if (t<= 0.0f){ p[0]=pnt[0]; p[1]=pnt[1]; return; }
if (t>=float(n-1)){ p[0]=pnt[n2-2]; p[1]=pnt[n2-1]; return; }
// select patch
i=floor(t); // start point of patch
t-=i; // parameter <0,1>
i<<=1; tt=t*t; ttt=tt*t;
// control points
ii=i-2; if (ii<0) ii=0; if (ii>=n2) ii=n2-2; p0=pnt+ii;
ii=i ; if (ii<0) ii=0; if (ii>=n2) ii=n2-2; p1=pnt+ii;
ii=i+2; if (ii<0) ii=0; if (ii>=n2) ii=n2-2; p2=pnt+ii;
ii=i+4; if (ii<0) ii=0; if (ii>=n2) ii=n2-2; p3=pnt+ii;
// loop all dimensions
for (i=0;i<2;i++)
{
// compute polynomial coeficients
d1=0.5*(p2[i]-p0[i]);
d2=0.5*(p3[i]-p1[i]);
a0=p1[i];
a1=d1;
a2=(3.0*(p2[i]-p1[i]))-(2.0*d1)-d2;
a3=d1+d2+(2.0*(-p2[i]+p1[i]));
// compute point coordinate
p[i]=a0+(a1*t)+(a2*tt)+(a3*ttt);
}
}
//---------------------------------------------------------------------------
void gl_draw()
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
// set 2D view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(1.0/5.0,1.0/500.0,1.0);
glTranslatef(-4.0,0.0,0.0);
// render lines
glColor3f(1.0,0.0,0.0);
glBegin(GL_LINE_STRIP);
float p[2],t;
for (t=0.0;t<=float(n-1);t+=0.1f)
{
getpnt(p,t);
glVertex2fv(p);
}
glEnd();
// render points
glPointSize(4.0);
glColor3f(0.0,0.0,1.0);
glBegin(GL_POINTS);
for (int i=0;i<n2;i+=2) glVertex2fv(pnt+i);
glEnd();
glPointSize(1.0);
glFinish();
SwapBuffers(hdc);
}
//---------------------------------------------------------------------------
Here preview:
As you can see it is simple you just need n
control points pnt
(I extracted from your graph) and just interpolate ... The getpnt
functions will compute any point on the curve addressed by parameter t=<0,n-1>
. Internally it just select which cubic patch to use and compute as single cubic curve. In gl_draw
you can see how to use it to obtain the points in between.
As your control points are uniformly distributed on the x
axis:
x = <1,7>
t = <0,6>
I can write:
x = t+1
t = x-1
so you can compute any point for any x
too...
The shape does not match your graph perfectly because the selected control points are not the correct ones. Any local minimum/maximum should be a control point and sometimes is safer to use also inflex points too. The starting and ending shape of the curve suggest hidden starting and ending control point which is not showed on the graph. You can use any number of points you need but beware if you break the x uniform distribution then you lose the ability to compute t
from x
directly!
As we do not know how the graph was created we can only guess ...
Seaborn lineplot - connecting dots of scatterplot
Ok, I have finally figured it out. The reason lineplot was so messy is because data was not properly sorted. When I sorted dataframe data by 'Y' values, the outcome was satisfactory.
data = {'X': [13, 13, 13, 12, 11], 'Y':[14, 11, 13, 15, 20], 'NumberOfPlanets':[2, 5, 2, 1, 2]}
cts = pd.DataFrame(data=data)
cts = cts.sort_values('Y')
plt.figure(figsize=(10,10))
plt.scatter(cts['X'], cts['Y'], zorder=1)
plt.plot(cts['X'], cts['Y'], zorder=2)
plt.show()
Now it works. Tested it also on other similar scatter points. Everything is fine :)
Thanks!
R: Connecting Points in Arbitrary Order
You can order your data like so:
my_data$order = c(1, 5, 2, 3, 4)
ggplot(my_data[order(my_data$order),], aes(x = x_cor, y = y_cor)) +
geom_path() +
geom_point(size = 2)
If you want to close the path, use geom_polygon
:
ggplot(my_data[order(my_data$order),], aes(x = x_cor, y = y_cor)) +
geom_polygon(fill = NA, color = "black") +
geom_point(size = 2)
Connecting points with ggplot in R
Another answer - that will work for this data, but not in general
example_df$group <- cut(example_df$y,
breaks = c(Inf, -0.8, -1.4, -Inf)) #breaks determined 'by eye'
example_df <- example_df[order(example_df$y), ] #sort by y
ggplot(example_df, aes(x = x, y = y, group = group)) +
geom_point() +
geom_path(colour = "blue")
Connecting points from different groups in a categorical X axis with ggplot
One approach is with interaction
:
library(ggplot2)
datframe %>%
ggplot(aes(x = factor_3, y = Abundance, color = factor_2, group = interaction(factor_1,factor_2)))+
geom_point() +
geom_line()
You might also consider including a second visual aesthetic to differentiate factor_1
.
datframe %>%
ggplot(aes(x = factor_3, y = Abundance, color = factor_2, linetype = factor_1, group = interaction(factor_1,factor_2)))+
geom_point() +
geom_line()
Data
set.seed(1)
datframe <- tibble(factor_1 = rep(c("A", "B", "C"), times =6),
Abundance = sample(x = 1:100, replace = T, size = 18),
factor_2 = rep(c("X", "Y"), each = 3, times = 3),
factor_3 = rep(c("Method 1", "Method 2", "Method 3"), each = 6))
Generating random points then connecting points less than certain distance away
I seemed to have figured out a solution (not ideal but works for this case).
The key was to use the \pgfmathparse
for performing the if statement to get a 0 or 1 to use in \ifnum
.
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}
\draw[step=0.5cm,color=gray] (-2.5,-2.5) grid (2.5,2.5);
\pgfmathsetseed{2}
\foreach \x in {1,...,10}
{
\pgfmathrandominteger{\a}{-240}{240}
\pgfmathrandominteger{\b}{-240}{240}
\fill [color=red,anchor=center](\a*0.01,\b*0.01) circle (0.1);
\pgfmathsetseed{2}
\foreach \y in {0,...,\x}
{
\pgfmathrandominteger{\c}{-240}{240}
\pgfmathrandominteger{\d}{-240}{240}
\tikzmath{\i=(\a*0.01-\c*0.01)^2;}
\tikzmath{\j=(\b*0.01-\d*0.01)^2;}
\tikzmath{\k=\i+\j;}
\pgfmathparse{\k < 4.0 ? 1 : 0}
\ifnum\pgfmathresult=1
\draw [color=blue,densely dotted] (\a*0.01,\b*0.01) -- (\c*0.01,\d*0.01);
\fi
};
};
\end{tikzpicture}
\end{document}
Add lines connecting points on R's contour plot
Is this response surface methodology? You can connect the dots with lines by the code lines(tabela[1:7, 2:3], col="black")
after creating the plot with the points.
A boxplot with lines connecting data points in python
You can use lineplot
here:
sns.lineplot(
data=df, x="score", y="player", units="court",
color=".7", estimator=None
)
Related Topics
Error When Exporting Dataframe to Text File in R
Fitting Logarithmic Curve in R
Changing the Appearance of Facet Labels Size
Subtract Values in One Dataframe from Another
How to Make Shinyapp to Use Environmental Variables When Deployed on the Web
Specify Function Parameters in Do.Call
R Cmd Check Latex Error: Fatal PDFlatex - Gui Framework Cannot Be Initialized
How to Round a Date to the Quarter Start/End
Obtaining Percent Scales Reflective of Individual Facets with Ggplot2
Major and Minor Tickmarks with Plotly
How to Replace the String Exactly Using Gsub()
Saving a File to Sharepoint with R
Remove Zombie Processes Using Parallel Package
How to Set Axis Ranges in Ggplot2 When Using a Log Scale
Mgcv Gam() Error: Model Has More Coefficients Than Data
How to Print the Name of Current Row When Using Apply in R
Print the Sourced R File to an Appendix Using Sweave
How to Use a Non-Ascii Symbol (E.G. £) in an R Package Function