Hi all,
Over the years there's been a number post on this forum about whether its possible to produce "zoomed-in" inset-plots within Stata. A number of work-arounds have been proposed:
The end result can be seen in the bottom panel of the graph below. Clearly, the inset plot is a useful visual aid when observations are so densely clustered. (note I don't currently have access to Stata, so am not able to use remove all the unnecessary filler)
In short, the method I use is to plot the zoomed-in observations on a second axis (as well as the main one), and then to simply make that axis invisible. The "trick", however, is to artificially (and somewhat randomly) alter the range of the second axis, so as to confine the inset plot within a small area of the main plot. To do this I use the excellent - addplot - package from SSC, which allows one to create the main graph, and then add separate plot layers on top of it (somewhat in line with the grammar of graphics which informs R's ggplot2 ). The same effect can potentially be achieved without addplot , though I have not yet tested it.
The first step is to plot the inset box within the main graph along the main graph axis (and optionally a smaller box to highlight the area to be zoomed in on, and lines connecting the two). This is easily done with addplot by plotting immediate scatter - scatteri - and then using - recast(line) - while ensuring that the norescaling option of addplot is specified so as to preserve the original plot dimensions.
The next, and final step, is then add the actual plots markers along a hidden second axis (be it scatter points, lines or really anything that Stata can offer). As I said above, the key is to alter the range of the second Y/X-axis so that the inset markers fall within the inset box. For this particular plot, I reduce the Y range from -0.2/0.2 on the main axis to -0.001/0.000975 on the inset axis so as to confine inset markers to that bottom half of the plot (that is, the bottom half of the second panel). The same logic applies to the X-axis range. To be sure, getting these axis ranges right is pretty much trial and error. But I've generally found that you will get rough idea after around 3 attempts, and then it's just a matter of making small iterative adjustments to get a good fit.
And that's pretty much it. The inset axes are then made invisible by adding xscale(axis(2)off), and once again include the norescaling option to preserve the dimensions of the main plot.
Axix ticks and label can be added pretty easily too once the second axis has been created. Axis ticks are added via addplot as immediate paired coordinates - pci - while the added text option - text - can be used to specify axis label values (or any other text).
And the plot with ticks and labels (this time used to generate a sort zoomed-out effect) 
Over the years there's been a number post on this forum about whether its possible to produce "zoomed-in" inset-plots within Stata. A number of work-arounds have been proposed:
- For adding a zoomed-in plot within a graph grid see https://www.statalist.org/forums/for...raph-after-mca
- For a solution that utilises external software see https://www.statalist.org/forums/for...hs-using-stata
The end result can be seen in the bottom panel of the graph below. Clearly, the inset plot is a useful visual aid when observations are so densely clustered. (note I don't currently have access to Stata, so am not able to use remove all the unnecessary filler)
In short, the method I use is to plot the zoomed-in observations on a second axis (as well as the main one), and then to simply make that axis invisible. The "trick", however, is to artificially (and somewhat randomly) alter the range of the second axis, so as to confine the inset plot within a small area of the main plot. To do this I use the excellent - addplot - package from SSC, which allows one to create the main graph, and then add separate plot layers on top of it (somewhat in line with the grammar of graphics which informs R's ggplot2 ). The same effect can potentially be achieved without addplot , though I have not yet tested it.
The first step is to plot the inset box within the main graph along the main graph axis (and optionally a smaller box to highlight the area to be zoomed in on, and lines connecting the two). This is easily done with addplot by plotting immediate scatter - scatteri - and then using - recast(line) - while ensuring that the norescaling option of addplot is specified so as to preserve the original plot dimensions.
Code:
*** Add inset plot axes and connecting lines addplot 2: (scatteri -.002 -.002 .002 -.002 .002 .00625 -.002 .00625 -.002 -.002, recast(line) lpattern(solid) lcolor(black)) /* Small inset box (highlighting the area we want to zoom in) */ (pcarrowi -.002 .00625 -.021 -.09, recast(line) lpattern(solid) lwidth(vthin) lcolor(black)) /* Lines connecting small inset box to main inset box */ (pci .002 -.002 -.0055 -.1385, lpattern(solid) lwidth(vthin) lcolor(black)) (scatteri -.021 -.09 -.021 -.1385 -.0055 -.1385 -.0055 -.09 -.021 -.09 , recast(line) lpattern(solid) lcolor(black)) /* Main inset box */ (pci -.021 -.133 -.0055 -.133, lpattern(shortdash) lcolor(black) lwidth(thin)) (pci -.013 -.1385 -.013 -.09, lpattern(shortdash) lcolor(black) lwidth(thin) norescaling legend(off)) /* Y/X-axis guide lines (dashed ) */
Code:
*** Plot inset markers on 2nd X-axis addplot 2: (scatter DFZdif_def DFZdif_mcap if pclass_1 == 1 & DFZdif_mcap <=.002, msymbol(oh) msize(small) mcolor(gs1%2) xaxis(2) yaxis(2) ylabel(-.0001 .000975, axis(2)) /* Group scatter no.1 */ xlabel(-.0007 .00725, axis(2)) yscale(axis(2) off) mlwidth(thin) jitter(.1)) (scatter DFZdif_def DFZdif_mcap if pclass_1 == 2 & DFZdif_mcap <=.002, msymbol(oh) msize(small) /* */ mcolor(gs5%25*1.2) xaxis(2) yaxis(2) ylabel(-.0001 .000975, axis(2)) xlabel(-.0007 .00725, axis(2)) yscale(axis(2) off) mlwidth(thin) jitter(.1)) /* Group scatter no.1 */ (scatter DFZdif_def DFZdif_mcap if pclass_1 == 3 & DFZdif_mcap <=.002, msymbol(oh) msize(small) mcolor(gs9%25*1.1) xaxis(2) yaxis(2) ylabel(-.0001 .000975, axis(2)) /* Group scatter no.3 */ xlabel(-.0007 .00725, axis(2)) yscale(axis(2) off) mlwidth(thin) jitter(.1)) (scatter DFZdif_def DFZdif_mcap if pclass_1 == 4 & DFZdif_mcap <=.002, msymbol(oh) msize(small) /* Group scatter no.4 */ mcolor(gs13%50) xaxis(2) yaxis(2) ylabel(-.0001 .000975, axis(2)) xlabel(-.0007 .00725, axis(2)) yscale(axis(2) off) xscale(axis(2)off) mlwidth(thin) norescaling legend(off))
Axix ticks and label can be added pretty easily too once the second axis has been created. Axis ticks are added via addplot as immediate paired coordinates - pci - while the added text option - text - can be used to specify axis label values (or any other text).
Code:
addplot 5: (pci 750 -2.23 750 -2.32, xaxis(2) yaxis(2) lpattern(solid) lwidth(thin) lcolor(black) text(750 -2.5 "750", size(9pt) xaxis(2) yaxis(2) just(left))) (pci 500 -2.23 500 -2.32, xaxis(2) yaxis(2) lpattern(solid) lwidth(thin) lcolor(black) text(500 -2.5 "500", size(9pt) xaxis(2) yaxis(2) just(left))) (pci 250 -2.23 250 -2.32, xaxis(2) yaxis(2) lpattern(solid) lwidth(thin) lcolor(black) text(250 -2.5 "250", size(9pt) xaxis(2) yaxis(2) just(left))) (pci 0 -2.23 0 -2.32, xaxis(2) yaxis(2) lpattern(solid) lwidth(thin) lcolor(black) text(0 -2.5 "0", size(9pt) xaxis(2) yaxis(2) just(left))) (pci 0 -2.15 0 2.25, xaxis(2) yaxis(2) lwidth(0.1) lpattern(shortdash) lcolor(black) norescaling)
Comment