Visit Jeremy's Blog.
 LinuxQuestions.org What is the math for proportionally plotting a chart?
 User Name Remember Me? Password
 Programming This forum is for all programming questions. The question does not have to be directly related to Linux and any language is fair game.

 11-26-2022, 09:03 AM #1 lucmove Senior Member   Registered: Aug 2005 Location: Brazil Distribution: Debian Posts: 1,450 Rep: What is the math for proportionally plotting a chart? Assuming I have a chart and know exactly how many pixels I have on width and height, I know what the highest and lowest plot values are going to be, and I want to display a y axis on the side with some regular interval values. For example: Code: ```y 50 x x x 40 x x x x 30 x x x x x 20 x x x 10 x 0 x-> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16``` I can draw that, but the plot values don't match the y axis indicator. So my problem is, what are the x/y pixel coordinates for value 25.6, or 34.7 or 44.1? And what if the y axis changes and goes from 70 to 210? Or from 300 to 1,700? How do I reliably calculate the x/y pixel chart coordinates across multiple scale scenarios? TIA
 11-26-2022, 09:32 AM #2 pan64 LQ Addict   Registered: Mar 2012 Location: Hungary Distribution: debian/ubuntu/suse ... Posts: 22,121 Rep: what language is it and what kind of display is it (console, graphical whatever or??) What tool is it at all?
11-26-2022, 10:42 AM   #3
jailbait
LQ Guru

Registered: Feb 2003
Location: Virginia, USA
Distribution: Debian 12
Posts: 8,346

Rep:
Quote:
 Originally Posted by lucmove Assuming I have a chart and know exactly how many pixels I have on width and height, I know what the highest and lowest plot values are going to be, and I want to display a y axis on the side with some regular interval values. For example: Code: ```y 50 x x x 40 x x x x 30 x x x x x 20 x x x 10 x 0 x-> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16``` I can draw that, but the plot values don't match the y axis indicator. So my problem is, what are the x/y pixel coordinates for value 25.6, or 34.7 or 44.1? And what if the y axis changes and goes from 70 to 210? Or from 300 to 1,700? How do I reliably calculate the x/y pixel chart coordinates across multiple scale scenarios? TIA
For the y axis you take the total number of pixels available (say 1800 after you take account of the labels on the x axis) and divide that by the maximum value of the Y axis (say 50 in your example). This gives you the number of pixels per unit on the y axis (1800/50 = 36 pixels per unit).

For the x axis you take the total number of pixels available (say 1100 after you take account of the labels on the y axis) and divide that by the maximum value of the Y axis (say 16 in your example). This gives you the number of pixels per unit on the y axis (1100/16 = 68 pixels per unit).

You can make your graph more readable if you leave a few extra pixels around all four sides to make a clean border.

You can also make a more readable graph if you only include the data range on the y axis. For example if your data was all in the range of 30 to 45 then showing a range of 25 to 50 gives a nicer presentation than a range of 0 through 50. In this case the number of pixels per unit on the y axis would be (1800/25 = 72). The formula for where to place a dot d on the y axis would be ((d-25) * 72).

A similar exercise can be done on the x axis when the label does not start at 0.

Last edited by jailbait; 11-26-2022 at 11:33 AM.

1 members found this post helpful.
11-26-2022, 10:57 AM   #4
lucmove
Senior Member

Registered: Aug 2005
Location: Brazil
Distribution: Debian
Posts: 1,450

Original Poster
Rep:
Quote:
 Originally Posted by jailbait For example if your data was all in the range of 30 to 45 then showing a range of 25 to 50 gives a nicer presentation than a range of 0 through 50. In this case the number of pixels per unit on the y axis would be (1800/25 = 72). The formula for where to place a dot d on the y axis would be ((d-30) * 120).
Excellent answer, thank you. But the part I really needed is still not clear. Why 120? Where did that number come from?

11-26-2022, 11:02 AM   #5
jailbait
LQ Guru

Registered: Feb 2003
Location: Virginia, USA
Distribution: Debian 12
Posts: 8,346

Rep:
Quote:
 Originally Posted by lucmove Excellent answer, thank you. But the part I really needed is still not clear. Why 120? Where did that number come from?
That number should be 72. I'll change it in the original post.

1 members found this post helpful.
11-26-2022, 11:04 AM   #6
lucmove
Senior Member

Registered: Aug 2005
Location: Brazil
Distribution: Debian
Posts: 1,450

Original Poster
Rep:
Quote:
 Originally Posted by jailbait That number should be 72. I'll change it in the original post.
Oh. OK. Thank you again.

11-26-2022, 11:12 AM   #7
lucmove
Senior Member

Registered: Aug 2005
Location: Brazil
Distribution: Debian
Posts: 1,450

Original Poster
Rep:
Quote:
 Originally Posted by pan64 what language is it and what kind of display is it (console, graphical whatever or??) What tool is it at all?
It's perl, but I don't want any code. I want the math. Writing the code is how I have my fun.
Thank you for your attention.

 11-26-2022, 01:59 PM #8 dugan LQ Guru   Registered: Nov 2003 Location: Canada Distribution: distro hopper Posts: 11,269 Rep: Wouldn't you just google "curve fitting"?
 11-26-2022, 02:23 PM #9 lucmove Senior Member   Registered: Aug 2005 Location: Brazil Distribution: Debian Posts: 1,450 Original Poster Rep: No, that formula is not working. Let's see. Number of pixels = 1800 range = 25 to 50 1800/25 = 72 dot d = ((d-25) * 72) Assuming dot d = 10, which is close to the bottom (pixel 0) dot 10 = ((10-25) * 72) dot 10 = (-15 * 72) dot 10 = -1080.0 So dot 10 would be plotted at -1080 in the y axis? That is wrong. It shouldn't be negative. Let's try another value for dot d. Number of pixels = 1800 range = 25 to 50 1800/25 = 72 dot d = ((d-25) * 72) Assuming dot d = 45, which is close to the top (pixel 1800) dot 45 = ((45-25) * 72) dot 10 = (20 * 72) dot 10 = 1440 1440 seems a bit too far from 1800. Now let's try some different figures and deal with fractions. Number of pixels = 1800 range = 10400 to 13800 1800/13800 = 0.13043478260869565 dot d = ((d-10400) * 0.13043478260869565) Assuming dot d = 10500, which is close to the bottom (pixel 0) dot 10500 = ((10500-10400) * 0.13043478260869565) dot 10 = (100 * 0.13043478260869565) dot 10 = 13.043478260869565 OK, looks good. Number of pixels = 1800 range = 10400 to 13800 1800/13800 = 0.13043478260869565 dot d = ((d-10400) * 0.13043478260869565) Assuming dot d = 13700, which is close to the top (pixel 1800) dot 13700 = ((13700-10400) * 0.13043478260869565) dot 13700 = (3300 * 0.13043478260869565) dot 13700 = 430.4347826086956 430 is VERY far from 1800! Back to the drawing board. :-(
11-26-2022, 03:44 PM   #10
astrogeek
Moderator

Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,278
Blog Entries: 24

Rep:
Quote:
 Originally Posted by lucmove No, that formula is not working. Let's see. Number of pixels = 1800 range = 25 to 50 1800/25 = 72 dot d = ((d-25) * 72) Assuming dot d = 10, which is close to the bottom (pixel 0) dot 10 = ((10-25) * 72) dot 10 = (-15 * 72) dot 10 = -1080.0 So dot 10 would be plotted at -1080 in the y axis? That is wrong. It shouldn't be negative.
Well, if the range of values, that is the y-axis of your graph is 25 to 50, then by definition you will have no dots with a value of 10 in the graph! The negative value tells you it is out of y-axis range.

If you have a lowest dot with a value of 10 then the lower end of the range must be 10 or less!

Then the formula would be something like this:

Code:
```range-min = 10
range-max = 50
pixels = 1800

pixels-per-y-unit = pixels / (range-max - range-min)

dot-y-coordinate = (dot - range-min) * pixels-per-y-unit

dot = 10 : dot-y-coordinate -> 0
dot = 25 : dot-y-coordinate -> 1125
dot = 50 : dot-y-coordinate -> 1800```
You must understand the formula to use it correctly.

If the range of actual values were 10 to 50 and you want to leave some pad at top and bottom then set range-min lower than 10 and the range-max greater than 50, 0 to 60 for example:

Code:
```range-min = 0
range-max = 60
pixels = 1800
...
dot = 10 : dot-y-coordinate -> 300
dot = 25 : dot-y-coordinate -> 750
dot = 50 : dot-y-coordinate -> 1500```

Last edited by astrogeek; 11-26-2022 at 05:12 PM.

1 members found this post helpful.
11-26-2022, 05:21 PM   #11
lucmove
Senior Member

Registered: Aug 2005
Location: Brazil
Distribution: Debian
Posts: 1,450

Original Poster
Rep:
Quote:
 Originally Posted by astrogeek Well, if the range of values, that is the y-axis of your graph is 25 to 50, then by definition you will have no dots with a value of 10 in the graph! The negative value tells you it is out of y-axis range. If you have a lowest dot with a value of 10 then the lower end of the range must be 10 or less!
Yes, my mistake. I'm sorry. Thank you for pointing that out.

Quote:
 Originally Posted by astrogeek Then the formula would be something like this: Code: ```range-min = 10 range-max = 50 pixels = 1800 pixels-per-y-unit = pixels / (range-max - range-min) dot-y-coordinate = (dot - range-min) * pixels-per-y-unit```

I have tested that formula in multiple scenarios and it seems to work well. Looks like this is solved now.
Thank you very much!

12-17-2022, 08:26 PM   #12
rnturn
Senior Member

Registered: Jan 2003
Location: Illinois (SW Chicago 'burbs)
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,820

Rep:
Quote:
 Originally Posted by lucmove It's perl, but I don't want any code. I want the math. Writing the code is how I have my fun.
You need to determine the limits in the size plot you wish to create. It seems you already have this. Establish the scaling that needs to done with each data point in both the X and Y directions: Xscale = (Xpxlmax - Xpxlmin) / (Xmax - Xmin). (Same for Y.) Apply the scaling to each point to, basically, turn the data coordinates to coordinates in the "pixel space". If either the X or Y data crosses 0.0, you'll need to apply an offset as well to get the data positioned around the X/Y axes correctly and within you plotting space. Tinkering with a small dataset should make it clear how this works.

I used to do stuff like to to get data plotted on pen plotters; things got hairy when there were multiple/stacked plots. I stopped caring about things like this when tools like Gnuplot did all of it for me. It's interesting to know how the guts of the tool works but if I'm more interested in seeing the plot and I'm no longer banging my head on the table trying to get a homegrown surface plot w/ hidden-line removal code to work, I'm more than happy.

Anyhoo... good luck.

1 members found this post helpful.
12-17-2022, 10:22 PM   #13
lucmove
Senior Member

Registered: Aug 2005
Location: Brazil
Distribution: Debian
Posts: 1,450

Original Poster
Rep:
Quote:
 Originally Posted by rnturn I stopped caring about things like this when tools like Gnuplot did all of it for me. It's interesting to know how the guts of the tool works but if I'm more interested in seeing the plot and I'm no longer banging my head on the table trying to get a homegrown surface plot w/ hidden-line removal code to work, I'm more than happy.
Gnuplot is nightmarishly difficult. Coding my own plotter from scratch is easier.

Not a lot of good plotters for Windows either. Most offerings today are exclusively online.

12-17-2022, 11:38 PM   #14
astrogeek
Moderator

Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,278
Blog Entries: 24

Rep:
Quote:
 Originally Posted by lucmove Gnuplot is nightmarishly difficult. Coding my own plotter from scratch is easier.
I thought so too, at one time, but learn it systematically and keep a reference set of your own worked out examples - it will reward you nicely!

Quote:
 Originally Posted by lucmove Not a lot of good plotters for Windows either. Most offerings today are exclusively online.
They know what your data is worth even when you do not... all your data are theirs this way!

1 members found this post helpful.
 12-18-2022, 01:38 AM #15 dugan LQ Guru   Registered: Nov 2003 Location: Canada Distribution: distro hopper Posts: 11,269 Rep: A lot of people these days use Python, Matplotlib and Jupyter Notebook, all of which are offline. Here are two links: https://towardsdatascience.com/makin...l-23c8a35c0d5d https://www.makeuseof.com/draw-graphs-jupyter-notebook/ 1 members found this post helpful.

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is Off HTML code is Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post captainentropy Programming 3 10-09-2013 09:00 PM knockout_artist Programming 7 11-25-2011 02:13 PM msbstar Linux - Newbie 7 04-12-2011 10:30 PM dar_beh_dar Linux - Kernel 3 05-20-2009 11:43 PM Four General 5 04-19-2006 08:02 PM

LinuxQuestions.org

All times are GMT -5. The time now is 08:38 AM.

 Contact Us - Advertising Info - Rules - Privacy - LQ Merchandise - Donations - Contributing Member - LQ Sitemap -