<p>Give @Giskards comments I'll put up my answer in the comments as answer. I usually fake the data and then use my favourite plotting program. For example here is the requested income substitution graph challenge created with R and GGplot2. For completeness I add the code, but given that it's quite long I add it to the end of my answer. Added bonus of GGplot/R is that if one is well versed with it it is simple to include LaTEX annotation.</p>
<p><a href="https://i.sstatic.net/ssOGt.png" rel="noreferrer"><img src="https://i.sstatic.net/ssOGt.png" alt="enter image description here" /></a></p>
<p>Making a similar graph in Excel is also doable. I'll admit though that Excel becomes a pain once we want multiple axes and scales, and the same probably applies to GGPlot. And of course Excel doesn't work well with LaTEX.</p>
<p>Code to generate graph (all parameters can be adjusted, the only thing that needs to be fixed afterwards is the vertical position of the arrows and the text).</p>
<pre><code>#Packages
require(ggplot2)
#Parameters
#Using a CD utility function for convenience and because it generates easy demands
#As the A in that function is just for scaling we'll set it to 1
#Exponent on utility function
alpha &lt;- 0.5
#Price of goods
p_x &lt;-1
p_y &lt;-1
#Price of x after price increase
p_x2 &lt;-4
#Budget
M &lt;- 10

#Basic numbers as input
df&lt;-data.frame(x_amount=seq(0,M/p_x,by=0.1))

#Budget constraint 1 &amp; 2 (formulated in y-x plane)
df<span class="math-container">$BC_1 &lt;-(M-p_x*df$</span>x_amount)/p_y
df<span class="math-container">$BC_2 &lt;-(M-p_x2*df$</span>x_amount)/p_y

#Calculating utility for correct indifference curves
#By the marginal spending rule alpha/(1-alpha)*(y/x)=p_x/p_y
#Therefore y=((1-alpha)/alpha)*(p_x/p_y)*x
#By the budget constraint y=(M-p_x*x)/p_y
#Using that and solving gives x=(M*alpha)/p_x and y=((1-alpha)*M)/p_y
#Utility indifference curve 1
U1&lt;-((M*alpha)/p_x)^alpha*(((1-alpha)*M)/p_y)^(1-alpha)
#Utility indifference curve 2
U2&lt;-((M*alpha)/p_x2)^alpha*(((1-alpha)*M)/p_y)^(1-alpha)

#Indifference curve 1
df<span class="math-container">$indif1&lt;-(U1/(df$</span>x_amount^alpha))^(1/(1-alpha))
#Indifference curve 2
df<span class="math-container">$indif2&lt;-(U2/(df$</span>x_amount^alpha))^(1/(1-alpha))

#To find the final budget constraint first identify the x and y value
#To do this we set the first derivative of indifference curve 1 equal to 
#the new -p_x2/p_y and find its root 
f1 &lt;- function (x) -alpha*(U1/x^alpha)^(1/(1-alpha))/((1-alpha)*x)+p_x2/p_y

Solution_x &lt;- uniroot(f1,c(0.1,20))$root
Solution_y &lt;- (U1/(Solution_x^alpha))^(1/(1-alpha))
#Determine the intercept

f2 &lt;- function(M) M-p_x2*Solution_x - p_y * Solution_y
M2 &lt;- uniroot(f2, c(0,30))$root

df<span class="math-container">$BC_3 &lt;- M2/p_y - p_x2/p_y * df$</span>x_amount

#Reshaped dataframe to long format
df_2 &lt;- data.frame(x_amount=rep(df<span class="math-container">$x_amount, times=5),
                   y_variables=c(df$</span>BC_1,df<span class="math-container">$BC_2,df$</span>indif1,df<span class="math-container">$indif2, df$</span>BC_3),
                   role=factor(rep( colnames(df)[2:6], each=length(df$x_amount)))
)

ggplot(data = df_2) +
  aes(x_amount, y_variables,colour=role)+
  geom_line(size=1)+
  ylim(0,20)+
  geom_vline(xintercept = Solution_x, size=1, linetype=3)+
  geom_vline(xintercept = (M*alpha)/p_x , size=1, linetype=3)+
  geom_vline(xintercept = (M*alpha)/p_x2, size=1, linetype=3)+
  geom_segment(x=(M*alpha)/p_x, y=3,yend=3, xend=Solution_x, colour=&quot;black&quot;, arrow = arrow(length = unit(0.25, &quot;cm&quot;)))+
  geom_segment(x=Solution_x, y=5,yend=5, xend=(M*alpha)/p_x2, colour=&quot;black&quot; ,arrow = arrow(length = unit(0.25, &quot;cm&quot;)))+
  geom_segment(x=(M*alpha)/p_x, y=0.8,yend=0.8, xend=(M*alpha)/p_x2, colour=&quot;black&quot;, arrow = arrow(length = unit(0.25, &quot;cm&quot;)))+
  annotate(&quot;text&quot;,x=3.2, y=3.7, label = &quot;Substitution effect&quot;, size=3)+
  annotate(&quot;text&quot;,x=1.9, y=5.3, label = &quot;Income effect&quot;, size=3)+
  annotate(&quot;text&quot;,x=3, y=1.2, label = &quot;Total effect&quot;, size=3)+
  ylab(&quot;Amount of y&quot;)+
  xlab(&quot;Amount of x&quot;)+
  theme(legend.position = &quot;none&quot;, 
        panel.background = element_rect(fill = NA), 
        panel.border = element_rect(linetype = 1 , fill = NA))
</code></pre>

CC BY-SA 4.0
2021-05-17T14:25:16.197Z
2021-05-17T14:25:16.197Z
Maarten Punt
<p>Obviously I'm talking about a theoretical graph not one where you can just plot the data. The only two options I can think of are just using shapes in word/powerpoint or using TikZ in Latex which is very time consuming.</p>
<p>I would be interested to know what your preferred methods are for drawing good looking digital graphs.</p>

CC BY-SA 4.0
2021-05-11T10:00:54.900Z
[Ipe](https://ipe.otfried.org/) is great. Allows you to add latex code and export to pdf (and edit later on).
tdm
CC BY-SA 4.0
2021-05-11T10:06:38.440Z
Why not simply generate the datapoints and then plot them in your favourite data visualization program?
Maarten Punt
CC BY-SA 4.0
2021-05-11T10:15:37.590Z
@HenryM I have read the question. I am just not seeing what kind of theoretical graph there would exist that you cannot create by simply making up the data and then plotting that instead. AFAIK any graph is just a representation of (possibly transformed) numbers.
Maarten Punt
CC BY-SA 4.0
2021-05-11T10:34:10.290Z
@MaartenPunt well yes but it adds an extra unnecessary step compared to just drawing a graph and presents scaling issues. Additionally many economics graphs need different annotations, multiple labels at intersections and many other things which are just much more efficient to just draw.
Henry M
CC BY-SA 4.0
2021-05-11T10:46:32.053Z
@MaartenPunt would you really want to plot a substitution v income effect graph with labels in excel?
Henry M
CC BY-SA 4.0
2021-05-11T11:00:42.400Z
@Henry Why would you assume that MaartenPunt's 'favourite data visualization program' is 'excel'? Personally I do what MaartenPunt suggest and simply code up the functions make the points for the graph and plot it, this I prefer to do in R. Not saying it is ideal, but having learned the software the trade-off between prettyness and speed of production usually favors just sticking to my 'favourite data visualization program'.
Jesper Hybel
CC BY-SA 4.0
2021-05-11T11:04:14.960Z
@HenryM you seem to want something that will give you publication grade graphs without any effort. I am sorry but there is no such thing. Tikz or Ipe mentioned above are all standards. Yes they are time consuming but they produce figures that are clear and precise - something that can’t be done in MS word. Additionally, as said by Maarten generating example using Python or R based on some generated datapoints is common technique that produces publication grade figures as well. I would not recommend doing serious research in excel but if that’s all you know generating figures there from data
1muflon1
CC BY-SA 4.0
2021-05-11T11:07:26.993Z
Would definitely give you better and accurate theoretical plots than trying to use shapes in word/PowerPoint - call me a snobbish academic in an ivory tower but if you present theoretical model with figures made with shapes I would take it as seriously as report written in comic sans on card board cutout
1muflon1
CC BY-SA 4.0
2021-05-11T14:43:19.367Z
@1muflon1: I can make graphs in Word that are visually indistinguishable from the ones done with TikZ, up to a difference in fonts. In fact, back in grad school, all my class notes (including all the graphs and equations) were taken with Word. That was before I learned TikZ, of course. But even as TikZ-proficient as I am now, I can't say that I could have taken the notes in TeX with the same visual quality under the same time constraint. MS Word can be very efficient if you're willing to sacrifice a small amount of precision.
Herr K.
CC BY-SA 4.0
2021-05-11T14:44:35.223Z
Ipe is what I used for formal purposes, but I also like [Desmos](https://www.desmos.com). Here is an [example](https://www.desmos.com/calculator/y3zqhrqm6z). There is definitely a learning curve, and the main focus of the site is interactivity, it is not an all purpose programming language.
Giskard
CC BY-SA 4.0
2021-05-11T14:48:26.813Z
@HenryM: I know of people who use [Inkscape](https://inkscape.org/), which supports hand-drawing and export to TeX. Some publishers use [Adobe Illustrator](https://www.adobe.com/products/illustrator.html), which is less TeX-friendly.
Herr K.
CC BY-SA 4.0
2021-05-11T15:13:27.700Z
Is there any reason why we are doing this in the comments and not as answers?
Giskard
<soft-question>
Soft question: How do you create/draw/plot economic graphs digitally?
Henry M
# Soft question: How do you create/draw/plot economic graphs digitally?

(Asked by: username_0 on 2021-05-11)

Obviously I'm talking about a theoretical graph not one where you can just plot the data. The only two options I can think of are just using shapes in word/powerpoint or using TikZ in Latex which is very time consuming.

I would be interested to know what your preferred methods are for drawing good looking digital graphs.

**Tags:** soft-question

> **Comments:**
> **username_1**: [Ipe](https://ipe.otfried.org/) is great. Allows you to add latex code and export to pdf (and edit later on).  
> **username_2**: Why not simply generate the datapoints and then plot them in your favourite data visualization program?  
> **username_2**: @HenryM I have read the question. I am just not seeing what kind of theoretical graph there would exist that you cannot create by simply making up the data and then plotting that instead. AFAIK any graph is just a representation of (possibly transformed) numbers.  
> **username_0**: @MaartenPunt well yes but it adds an extra unnecessary step compared to just drawing a graph and presents scaling issues. Additionally many economics graphs need different annotations, multiple labels at intersections and many other things which are just much more efficient to just draw.  
> **username_0**: @MaartenPunt would you really want to plot a substitution v income effect graph with labels in excel?  
> **username_3**: @Henry Why would you assume that MaartenPunt's 'favourite data visualization program' is 'excel'? Personally I do what MaartenPunt suggest and simply code up the functions make the points for the graph and plot it, this I prefer to do in R. Not saying it is ideal, but having learned the software the trade-off between prettyness and speed of production usually favors just sticking to my 'favourite data visualization program'.  
> **username_4**: @HenryM you seem to want something that will give you publication grade graphs without any effort. I am sorry but there is no such thing. Tikz or Ipe mentioned above are all standards. Yes they are time consuming but they produce figures that are clear and precise - something that can’t be done in MS word. Additionally, as said by Maarten generating example using Python or R based on some generated datapoints is common technique that produces publication grade figures as well. I would not recommend doing serious research in excel but if that’s all you know generating figures there from data  
> **username_4**: Would definitely give you better and accurate theoretical plots than trying to use shapes in word/PowerPoint - call me a snobbish academic in an ivory tower but if you present theoretical model with figures made with shapes I would take it as seriously as report written in comic sans on card board cutout  
> **username_5**: @username_4: I can make graphs in Word that are visually indistinguishable from the ones done with TikZ, up to a difference in fonts. In fact, back in grad school, all my class notes (including all the graphs and equations) were taken with Word. That was before I learned TikZ, of course. But even as TikZ-proficient as I am now, I can't say that I could have taken the notes in TeX with the same visual quality under the same time constraint. MS Word can be very efficient if you're willing to sacrifice a small amount of precision.  
> **username_6**: Ipe is what I used for formal purposes, but I also like [Desmos](https://www.desmos.com). Here is an [example](https://www.desmos.com/calculator/y3zqhrqm6z). There is definitely a learning curve, and the main focus of the site is interactivity, it is not an all purpose programming language.  
> **username_5**: @HenryM: I know of people who use [Inkscape](https://inkscape.org/), which supports hand-drawing and export to TeX. Some publishers use [Adobe Illustrator](https://www.adobe.com/products/illustrator.html), which is less TeX-friendly.  
> **username_6**: Is there any reason why we are doing this in the comments and not as answers?  

---

## 1 answers

### Answer by username_2 on 2021-05-17. Score: 5 | Accepted answer

Give @username_6s comments I'll put up my answer in the comments as answer. I usually fake the data and then use my favourite plotting program. For example here is the requested income substitution graph challenge created with R and GGplot2. For completeness I add the code, but given that it's quite long I add it to the end of my answer. Added bonus of GGplot/R is that if one is well versed with it it is simple to include LaTEX annotation.

Making a similar graph in Excel is also doable. I'll admit though that Excel becomes a pain once we want multiple axes and scales, and the same probably applies to GGPlot. And of course Excel doesn't work well with LaTEX.
Code to generate graph (all parameters can be adjusted, the only thing that needs to be fixed afterwards is the vertical position of the arrows and the text).
#Packages
require(ggplot2)
#Parameters
#Using a CD utility function for convenience and because it generates easy demands
#As the A in that function is just for scaling we'll set it to 1
#Exponent on utility function
alpha <- 0.5
#Price of goods
p_x <-1
p_y <-1
#Price of x after price increase
p_x2 <-4
#Budget
M <- 10

#Basic numbers as input
df<-data.frame(x_amount=seq(0,M/p_x,by=0.1))

#Budget constraint 1 & 2 (formulated in y-x plane)
df$BC_1 <-(M-p_x*df$x_amount)/p_y
df$BC_2 <-(M-p_x2*df$x_amount)/p_y

#Calculating utility for correct indifference curves
#By the marginal spending rule alpha/(1-alpha)*(y/x)=p_x/p_y
#Therefore y=((1-alpha)/alpha)*(p_x/p_y)*x
#By the budget constraint y=(M-p_x*x)/p_y
#Using that and solving gives x=(M*alpha)/p_x and y=((1-alpha)*M)/p_y
#Utility indifference curve 1
U1<-((M*alpha)/p_x)^alpha*(((1-alpha)*M)/p_y)^(1-alpha)
#Utility indifference curve 2
U2<-((M*alpha)/p_x2)^alpha*(((1-alpha)*M)/p_y)^(1-alpha)

#Indifference curve 1
df$indif1<-(U1/(df$x_amount^alpha))^(1/(1-alpha))
#Indifference curve 2
df$indif2<-(U2/(df$x_amount^alpha))^(1/(1-alpha))

#To find the final budget constraint first identify the x and y value
#To do this we set the first derivative of indifference curve 1 equal to 
#the new -p_x2/p_y and find its root 
f1 <- function (x) -alpha*(U1/x^alpha)^(1/(1-alpha))/((1-alpha)*x)+p_x2/p_y

Solution_x <- uniroot(f1,c(0.1,20))$root
Solution_y <- (U1/(Solution_x^alpha))^(1/(1-alpha))
#Determine the intercept

f2 <- function(M) M-p_x2*Solution_x - p_y * Solution_y
M2 <- uniroot(f2, c(0,30))$root

df$BC_3 <- M2/p_y - p_x2/p_y * df$x_amount

#Reshaped dataframe to long format
df_2 <- data.frame(x_amount=rep(df$x_amount, times=5),
                   y_variables=c(df$BC_1,df$BC_2,df$indif1,df$indif2, df$BC_3),
                   role=factor(rep( colnames(df)[2:6], each=length(df$x_amount)))
)

ggplot(data = df_2) +
  aes(x_amount, y_variables,colour=role)+
  geom_line(size=1)+
  ylim(0,20)+
  geom_vline(xintercept = Solution_x, size=1, linetype=3)+
  geom_vline(xintercept = (M*alpha)/p_x , size=1, linetype=3)+
  geom_vline(xintercept = (M*alpha)/p_x2, size=1, linetype=3)+
  geom_segment(x=(M*alpha)/p_x, y=3,yend=3, xend=Solution_x, colour="black", arrow = arrow(length = unit(0.25, "cm")))+
  geom_segment(x=Solution_x, y=5,yend=5, xend=(M*alpha)/p_x2, colour="black" ,arrow = arrow(length = unit(0.25, "cm")))+
  geom_segment(x=(M*alpha)/p_x, y=0.8,yend=0.8, xend=(M*alpha)/p_x2, colour="black", arrow = arrow(length = unit(0.25, "cm")))+
  annotate("text",x=3.2, y=3.7, label = "Substitution effect", size=3)+
  annotate("text",x=1.9, y=5.3, label = "Income effect", size=3)+
  annotate("text",x=3, y=1.2, label = "Total effect", size=3)+
  ylab("Amount of y")+
  xlab("Amount of x")+
  theme(legend.position = "none", 
        panel.background = element_rect(fill = NA), 
        panel.border = element_rect(linetype = 1 , fill = NA))


---

