hughjonesd / ggmagnify

Create a magnified inset of part of a ggplot object
https://hughjonesd.github.io/ggmagnify/
Other
275 stars 3 forks source link

ggmagnify can magnify irregular areas #4

Closed chuiqin closed 1 year ago

chuiqin commented 1 year ago

Thanks for developing such a great tool. I found out that ggmagnify can only magnify the graph in regular areas. But in the visualization of single-cell transcriptome sequencing, people are more inclined to zoom in on a specific cell subpopulation. However, the shape of cell subpopulations is irregular. Some R packages ggunchull and ggforce have advantages in drawing irregular graphics, but they cannot magnify the graphics and are not as beautiful and natural as ggmagnify. Looking forward to the new version of ggmagnify that can magnify irregular areas. I will continue to follow your work! Thank you very much!

hughjonesd commented 1 year ago

I know it would be cool... but this is just a one-day hack! I would bug @thomasp85 to create a ggmagnify-style geom in ggforce. Then you'd also get facetting etc.

hughjonesd commented 1 year ago

You can hack this yourself with a bit of work:

dat <- data.frame(x = rnorm(100), y= rnorm(100), z = sample(5,100,replace=T))
ggp <- ggplot(dat, aes(x, y, color = z)) + geom_point() + xlim(-2,2) + ylim(-2,2)
ggp
v <- viewport(x = .3, y = .3, width = .35, height = .35, mask=circleGrob(gp=gpar(fill=rgb(0,0,0,1))))
pushViewport(v)
ggm <- ggmagnify(ggp, xlim = 0:1, ylim = 0:1, inset_xlim = c(-2, 0), inset_ylim = c(-2,0))
grid.draw(ggplotGrob(ggm$inset))
grid.draw(circleGrob(gp = gpar(color="black", fill = NA)))

Zoom and target lines are left as an exercise :-)

chuiqin commented 1 year ago

You can hack this yourself with a bit of work:你可以通过一些工作自己破解这个:

dat <- data.frame(x = rnorm(100), y= rnorm(100), z = sample(5,100,replace=T))
ggp <- ggplot(dat, aes(x, y, color = z)) + geom_point() + xlim(-2,2) + ylim(-2,2)
ggp
v <- viewport(x = .3, y = .3, width = .35, height = .35, mask=circleGrob(gp=gpar(fill=rgb(0,0,0,1))))
pushViewport(v)
ggm <- ggmagnify(ggp, xlim = 0:1, ylim = 0:1, inset_xlim = c(-2, 0), inset_ylim = c(-2,0))
grid.draw(ggplotGrob(ggm$inset))
grid.draw(circleGrob(gp = gpar(color="black", fill = NA)))

Zoom and target lines are left as an exercise :-)缩放和目标线留作练习:-)

Thank you for your prompt reply. After I ran your sample code, I realized that you may have misunderstood me because of my vague description. In this sample code, ggm <- ggmagnify(ggp, xlim = 0:1, ylim = 0:1, inset_xlim = c(-2, 0), inset_ylim = c(-2,0)), it still It is a regular area that zooms in on the x-axis 0 to 1 and the y-axis 0 to 1. For your convenience, I drew a sketch by hand, I hope you don't mind it.

image

hughjonesd commented 1 year ago

I understand. I think honestly, a really irregular area, you had better do manually. The simplest thing would just be to copy the closest rectangle, set target and inset = FALSE, and draw the outlines manually.

chuiqin commented 1 year ago

Thank you for your reply! I combined the R packages ggunchull and ggmagnify in a clever way to draw irregular region graphics. I use the R package ggunchull to draw irregular curves. I use the R package ggmagnify to create a magnification effect. I set the two numbers in the parameters xlim and ylim in the ggmagnify function close enough so that the magnification effect looks like it starts from one point. But when I want to replace the image in ggm$inset with a brand new ggpolot2 object, I encounter failure. In the top right box, the brand new ggplot2 object is a grey. I wonder, if ggmagnify can support ggplot2 objects with ggm$inset set to either. This ggplot2 object can maintain its original appearance without being partially enlarged. If possible, the ggmagnify package can be used to display the results of re-clustering certain cell subpopulations in single-cell transcriptome data. I thought it would be a cool thing. Looking forward to your reply! image

hughjonesd commented 1 year ago

I guess my feeling is, if you want to put something entirely new in the inset, then ggmagnify is not the right solution - have you tried cowplot?

hughjonesd commented 1 year ago

Actually coming back to this.... it might even be possible. Are you interested in trying this? You'd need to pass a mask argument into geom_magnify(), and then deal with it in draw_panel - probably resizing it to the size of the inset rectangle, masking the inset with it, and drawing a border round it.

hughjonesd commented 1 year ago

OK, you got your wish!

Please try out:

remotes::install_github("hughjonesd/ggmagnify@experiment-arbitrary-mask")

You should then be able to magnify an arbitrary area by passing in a grid grob.

The border lines aren't working perfectly yet.

hughjonesd commented 1 year ago

If you have a good example of using this in a scientific plot, and you can share it, that would be great for the README!