|
| 1 | +--- |
| 2 | +Title: User Defined Scaling - ScottPlot FAQ |
| 3 | +Description: How to create a plot with a known units-per-pixel scaling |
| 4 | +date: 2025-02-24 |
| 5 | +--- |
| 6 | + |
| 7 | +## User Defined Scaling |
| 8 | + |
| 9 | +Plots which require a known "real world" scaling can setup a custom axis rule to |
| 10 | +enforce desired pixels-per-unit scaling at render time. Examples include: |
| 11 | + |
| 12 | +* Create a plot where the horizontal axis units is millimeters when printed |
| 13 | +* Create a plot where the horizontal axis is pixels |
| 14 | +* Place a tick mark every 50 pixels apart |
| 15 | + |
| 16 | +## Static Example |
| 17 | + |
| 18 | +This example demonstrates how to create a plot in a Console Application where each unit on the horizontal axis spans exactly 5 pixels. |
| 19 | + |
| 20 | +```cs |
| 21 | +using ScottPlot; |
| 22 | + |
| 23 | +// create a plot and add sample data |
| 24 | +Plot myPlot = new(); |
| 25 | +myPlot.Add.Signal(Generate.Sin(100, oscillations: 5)); |
| 26 | + |
| 27 | +// use a fixed layout system so we know how large the plot is in pixel units |
| 28 | +PixelRect dataRect = new(left: 50, right: 350, bottom: 250, top: 50); |
| 29 | +myPlot.Layout.Fixed(dataRect); |
| 30 | + |
| 31 | +// set axis limits to achieve a desired "pixels per unit" scaling |
| 32 | +float pixelsPerUnit = 5; |
| 33 | +float leftEdge = 0; |
| 34 | +float rightEdge = dataRect.Width / pixelsPerUnit; |
| 35 | +myPlot.Axes.SetLimitsX(leftEdge, rightEdge); |
| 36 | + |
| 37 | +// The final figure should be the data rectangle expanded to allow for axis labels |
| 38 | +PixelRect figureRect = dataRect.Expand(50); |
| 39 | +myPlot.SavePng("test.png", (int)figureRect.Width, (int)figureRect.Height); |
| 40 | +``` |
| 41 | + |
| 42 | + |
| 43 | + |
| 44 | +## Interactive Example |
| 45 | + |
| 46 | +This example uses Windows Forms, but the strategy can be applied to any interactive |
| 47 | +user control or console application. |
| 48 | + |
| 49 | +```cs |
| 50 | +public partial class Form1 : Form |
| 51 | +{ |
| 52 | + public Form1() |
| 53 | + { |
| 54 | + InitializeComponent(); |
| 55 | + |
| 56 | + // add sample data |
| 57 | + formsPlot1.Plot.Add.Signal(Generate.Sin(200, oscillations: 5)); |
| 58 | + |
| 59 | + // add our custom scaling rule |
| 60 | + FixedScalingAxisRule rule = new(); |
| 61 | + formsPlot1.Plot.Axes.Rules.Add(rule); |
| 62 | + } |
| 63 | + |
| 64 | + class FixedScalingAxisRule : IAxisRule |
| 65 | + { |
| 66 | + float PixelsPerUnit { get; set; } = 5; |
| 67 | + float LeftEdge { get; set; } = 0; |
| 68 | + |
| 69 | + public void Apply(RenderPack rp, bool beforeLayout) |
| 70 | + { |
| 71 | + if (beforeLayout) |
| 72 | + return; |
| 73 | + |
| 74 | + float rightEdge = rp.DataRect.Width / PixelsPerUnit; |
| 75 | + rp.Plot.Axes.SetLimitsX(LeftEdge, rightEdge); |
| 76 | + } |
| 77 | + } |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | + |
0 commit comments